File: /home/lgooir/.trash/elementor/includes/template-library/classes/class-media-collector.php
<?php
namespace Elementor\TemplateLibrary\Classes;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Elementor media collector.
*
* Collects media URLs during export and creates a media ZIP file.
*/
class Media_Collector {
/**
* Filename for the media mapping JSON file within the ZIP.
*/
private const MAPPING_FILENAME = 'media-mapping.json';
/**
* Collected media URLs and their metadata.
*
* @var array
*/
private $collected_media = [];
/**
* Temporary directory for media files.
*
* @var string
*/
private $temp_dir = '';
public function __construct() {
add_action( 'elementor/templates/collect_media_url', [ $this, 'collect_media_url' ], 10, 2 );
}
/**
* Start media collection for export (Step 1: Collect URLs).
*/
public function start_collection() {
$this->collected_media = [];
}
/**
* Start media processing (Step 2: Download media files and create zip).
*/
public function start_processing() {
$this->temp_dir = \Elementor\Plugin::$instance->uploads_manager->create_unique_dir();
}
public function collect_media_url( string $url, array $media_data = [] ) {
if ( ! $this->is_media_url( $url ) || isset( $this->collected_media[ $url ] ) ) {
return;
}
$this->collected_media[ $url ] = true;
}
/**
* Process a single media URL (Step 2: Download and save).
*/
public function process_media_url( string $url ) {
if ( ! $this->is_media_url( $url ) ) {
return false;
}
$local_filename = $this->download_and_save_media( $url );
if ( $local_filename ) {
$this->collected_media[ $url ] = $local_filename;
return $local_filename;
}
return false;
}
private function download_and_save_media( string $url ) {
if ( $this->is_local_url( $url ) ) {
$local_file_path = $this->get_local_file_path( $url );
if ( $local_file_path && file_exists( $local_file_path ) ) {
return $this->copy_local_file( $local_file_path, $url );
}
}
return $this->download_via_http( $url );
}
private function is_local_url( string $url ): bool {
$site_url = get_site_url();
$home_url = get_home_url();
return strpos( $url, $site_url ) === 0 || strpos( $url, $home_url ) === 0;
}
private function get_local_file_path( string $url ) {
$site_url = get_site_url();
$home_url = get_home_url();
$relative_path = str_replace( [ $site_url, $home_url ], '', $url );
$relative_path = ltrim( $relative_path, '/' );
$upload_dir = wp_upload_dir();
$uploads_path = $upload_dir['basedir'];
$possible_paths = [
$uploads_path . '/' . $relative_path,
ABSPATH . $relative_path,
$uploads_path . '/' . basename( $url ),
];
foreach ( $possible_paths as $path ) {
if ( file_exists( $path ) ) {
return $path;
}
}
return false;
}
private function copy_local_file( string $source_path, string $original_url ) {
$original_filename = basename( $original_url );
$extension = pathinfo( $original_filename, PATHINFO_EXTENSION );
$name_without_extension = pathinfo( $original_filename, PATHINFO_FILENAME );
$unique_filename = sanitize_file_name( $name_without_extension . '_' . uniqid() . '.' . $extension );
$destination_path = $this->temp_dir . '/' . $unique_filename;
$copied = copy( $source_path, $destination_path );
return $copied ? $unique_filename : false;
}
private function download_via_http( string $url ) {
$response = wp_safe_remote_get( $url, [
'timeout' => 30,
'user-agent' => 'Elementor Template Exporter',
] );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return false;
}
$file_content = wp_remote_retrieve_body( $response );
if ( empty( $file_content ) ) {
return false;
}
$original_filename = basename( $url );
$extension = pathinfo( $original_filename, PATHINFO_EXTENSION );
$name_without_extension = pathinfo( $original_filename, PATHINFO_FILENAME );
$unique_filename = sanitize_file_name( $name_without_extension . '_' . uniqid() . '.' . $extension );
$file_path = $this->temp_dir . '/' . $unique_filename;
$saved = file_put_contents( $file_path, $file_content );
return $saved ? $unique_filename : false;
}
public function get_collected_urls(): array {
return array_keys( $this->collected_media );
}
public function process_media_collection( array $media_urls ) {
$this->start_processing();
foreach ( $media_urls as $url ) {
$this->process_media_url( $url );
}
return $this->create_media_zip();
}
public function create_media_zip() {
if ( empty( $this->collected_media ) ) {
return null;
}
if ( ! class_exists( '\ZipArchive' ) ) {
return null;
}
$zip = new \ZipArchive();
$zip_filename = 'media-' . uniqid() . '.zip';
$zip_path = $this->temp_dir . '/' . $zip_filename;
if ( $zip->open( $zip_path, \ZipArchive::CREATE ) !== true ) {
return null;
}
$mapping = [];
foreach ( $this->collected_media as $url => $filename ) {
if ( is_string( $filename ) ) {
$file_path = $this->temp_dir . '/' . $filename;
if ( file_exists( $file_path ) ) {
$zip->addFile( $file_path, $filename );
$mapping[ $url ] = $filename;
}
}
}
if ( empty( $mapping ) ) {
$zip->close();
return null;
}
$mapping_json = wp_json_encode( $mapping, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
$zip->addFromString( self::MAPPING_FILENAME, $mapping_json );
$zip->close();
return $zip_path;
}
public function cleanup() {
if ( $this->temp_dir ) {
\Elementor\Plugin::$instance->uploads_manager->remove_file_or_dir( $this->temp_dir );
}
}
private function is_media_url( $url ) {
if ( ! is_string( $url ) || empty( $url ) ) {
return false;
}
if ( strpos( $url, 'data:' ) === 0 ) {
return false;
}
$allowed_mime_types = get_allowed_mime_types();
$file_extension = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
foreach ( $allowed_mime_types as $pattern => $mime_type ) {
$pattern_regex = '/^(' . str_replace( '|', '|', $pattern ) . ')$/i';
if ( preg_match( $pattern_regex, $file_extension ) ) {
return true;
}
}
return false;
}
}