PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.5.3
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.5.3
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
← All changes | includes/Core/Importer/WPImport.php +301 -89 3.1.13.5.3 View file →
@@ -2,8 +2,9 @@
2 2
3 3 namespace Templately\Core\Importer;
4 4
5 5 use Templately\Core\Importer\Parsers\WXR_Parser;
6 +use Templately\Core\Importer\Runners\Loop;
6 7 use Templately\Core\Importer\Utils\Utils;
7 8 use Templately\Utils\Helper;
8 9 use WP_Error;
9 10 use WP_Importer;
@@ -47,8 +48,11 @@
47 48 }
48 49 }
49 50
50 51 class WPImport extends WP_Importer {
52 + use LogHelper;
53 + use Loop;
54 +
51 55 const DEFAULT_BUMP_REQUEST_TIMEOUT = 60;
52 56 const DEFAULT_ALLOW_CREATE_USERS = true;
53 57 const DEFAULT_IMPORT_ATTACHMENT_SIZE_LIMIT = 0; // 0 = unlimited.
54 58
@@ -55,8 +59,12 @@
55 59 /**
56 60 * @var string
57 61 */
58 62 private $requested_file_path;
63 + /**
64 + * @var string
65 + */
66 + private $import_data_key;
59 67
60 68 /**
61 69 * @var array
62 70 */
@@ -62,8 +70,13 @@
62 70 */
63 71 private $args;
64 72
65 73 /**
74 + * @var FullSiteImport
75 + */
76 + private $origin;
77 +
78 + /**
66 79 * @var array
67 80 */
68 81 private $output = [
69 82 'status' => 'failed',
@@ -74,8 +87,18 @@
74 87 * WXR attachment ID
75 88 */
76 89 private $id;
77 90
91 + /**
92 + * @var mixed
93 + */
94 + private $json;
95 +
96 + /**
97 + * @var string
98 + */
99 + private $session_id;
100 +
78 101 // Information to import from WXR file.
79 102 private $version;
80 103 private $authors = [];
81 104 public $posts = [];
@@ -110,8 +133,25 @@
110 133 private $terms_meta = [];
111 134
112 135 public static $_replace_image_ids = [];
113 136
137 +
138 + public $backup_attributes = [
139 + 'output',
140 + 'url_remap',
141 + '_replace_image_ids',
142 + 'menu_item_orphans',
143 + 'processed_menu_items',
144 + 'post_orphans',
145 + 'processed_posts',
146 + 'featured_images',
147 + 'mapped_terms_slug',
148 + 'processed_terms',
149 + 'processed_authors',
150 + 'author_mapping',
151 + ];
152 +
153 +
114 154 /**
115 155 * Parses filename from a Content-Disposition header value.
116 156 *
117 157 * As per RFC6266:
@@ -287,9 +327,10 @@
287 327
288 328 wp_defer_term_counting( true );
289 329 wp_defer_comment_counting( true );
290 330
291 - do_action( 'import_start', $this );
331 + do_action( 'import_start' );
332 + do_action( 'templately_import_start', $this );
292 333
293 334 return true;
294 335 }
295 336
@@ -353,8 +394,14 @@
353 394 if ( ! isset( $this->args['imported_authors'] ) ) {
354 395 return;
355 396 }
356 397
398 +
399 + $processed_templates = $this->get_loop_result([], $this->import_data_key);
400 + if (!empty($processed_templates)) {
401 + return;
402 + }
403 +
357 404 $create_users = apply_filters( 'import_allow_create_users', self::DEFAULT_ALLOW_CREATE_USERS );
358 405
359 406 foreach ( (array) $this->args['imported_authors'] as $i => $old_login ) {
360 407 // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
@@ -409,8 +456,10 @@
409 456 }
410 457 $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
411 458 }
412 459 }
460 +
461 + $this->set_loop_result( true, $this->import_data_key );
413 462 }
414 463
415 464 /**
416 465 * Create new terms based on import information
@@ -424,8 +473,14 @@
424 473 'succeed' => [],
425 474 'failed' => [],
426 475 ];
427 476
477 + $processed_templates = $this->get_loop_result([], "wp_import_terms_" . $this->import_data_key);
478 + if (!empty($processed_templates)) {
479 + $result = $this->get_loop_result([], "wp_import_terms_" . $this->import_data_key);
480 + return $result;
481 + }
482 +
428 483 $this->terms = apply_filters( 'wp_import_terms', $this->terms );
429 484 if ( empty( $this->terms ) ) {
430 485 return $result;
431 486 }
@@ -505,8 +560,10 @@
505 560 }
506 561
507 562 unset( $this->terms );
508 563
564 + // Add the template to the processed templates and update the session data
565 + $this->set_loop_result( $result, "wp_import_terms_" . $this->import_data_key);
509 566 return $result;
510 567 }
511 568
512 569 /**
@@ -576,42 +633,59 @@
576 633 *
577 634 * @return array the ids of succeed/failed imported posts.
578 635 */
579 636 private function process_posts(): array {
580 - $result = [
581 - 'succeed' => [],
582 - 'failed' => [],
583 - ];
637 + $backup_key = "wp_import_post_" . $this->import_data_key;
584 638
585 639 $this->posts = apply_filters( 'wp_import_posts', $this->posts );
586 640
587 - foreach ( $this->posts as $post ) {
588 - $post = apply_filters( 'wp_import_post_data_raw', $post );
641 + $results = $this->loop( $this->posts, function($key, $post, $result ) {
589 642
643 + $result = !empty($result) ? $result : [
644 + 'succeed' => [],
645 + 'failed' => [],
646 + ];
647 +
648 + $original_post_id = $post['post_id'];
649 + $post = apply_filters( 'wp_import_post_data_raw', $post, $this );
650 +
651 + if(empty($post)){
652 + return $result;
653 + }
654 +
655 + if(!is_array($post) && is_numeric($post)){
656 + $result['succeed'][ $original_post_id ] = $post;
657 + return $result;
658 + }
659 +
590 660 if ( ! post_type_exists( $post['post_type'] ) ) {
591 661 /* translators: 1: Post title, 2: Post type. */
592 662 $this->output['errors'][] = sprintf( esc_html__( 'Failed to import %1$s: Invalid post type %2$s', 'elementor' ), $post['post_title'], $post['post_type'] );
593 663 do_action( 'wp_import_post_exists', $post );
594 - continue;
664 + return $result;
595 665 }
596 666
597 667 if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) {
598 - continue;
668 + return $result;
599 669 }
600 670
601 671 if ( 'auto-draft' === $post['status'] ) {
602 - continue;
672 + return $result;
603 673 }
604 674
675 + if(!empty($post['post_content']) && !empty($post['post_id'])){
676 + $post['post_content'] = Utils::import_and_replace_attachments($post['post_content'], $post['post_id']);
677 + }
678 +
605 679 if ( 'nav_menu_item' === $post['post_type'] ) {
606 680 $result['succeed'] += $this->process_menu_item( $post );
607 - continue;
681 + return $result;
608 682 }
609 683
610 684 if ( 'wp_navigation' === $post['post_type'] ) {
611 685 $processed = $this->process_navigation( $post );
612 686 if ( ! $processed ) {
613 - continue;
687 + return $result;
614 688 }
615 689 }
616 690
617 691 $post_type_object = get_post_type_object( $post['post_type'] );
@@ -651,9 +725,12 @@
651 725 'post_type' => $post['post_type'],
652 726 'post_password' => $post['post_password'],
653 727 ];
654 728
655 - $original_post_id = $post['post_id'];
729 + if(isset($post['original_attachment_url'])){
730 + $postdata['original_attachment_url'] = $post['original_attachment_url'];
731 + }
732 +
656 733 $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
657 734
658 735 $postdata = wp_slash( $postdata );
659 736
@@ -658,9 +735,9 @@
658 735 $postdata = wp_slash( $postdata );
659 736
660 737 if ( 'attachment' === $postdata['post_type'] ) {
661 738 $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid'];
662 -
739 + $attachment_sizes = [];
663 740 // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
664 741 // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
665 742 $postdata['upload_date'] = $post['post_date'];
666 743 if ( isset( $post['postmeta'] ) ) {
@@ -668,14 +745,19 @@
668 745 if ( '_wp_attached_file' === $meta['key'] ) {
669 746 if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) {
670 747 $postdata['upload_date'] = $matches[0];
671 748 }
672 - break;
749 + // break;
673 750 }
751 + else if ( '_wp_attachment_metadata' === $meta['key'] ) {
752 + $attachment_metadata = maybe_unserialize( $meta['value'] );
753 + $attachment_sizes = $attachment_metadata['sizes'] ?? [];
754 + // break;
755 + }
674 756 }
675 757 }
676 758
677 - $post_id = $this->process_attachment( $postdata, $remote_url );
759 + $post_id = $this->process_attachment( $postdata, $remote_url, $attachment_sizes, $original_post_id );
678 760 $comment_post_id = $post_id;
679 761 } else {
680 762 $post_id = wp_insert_post( $postdata, true );
681 763
@@ -696,9 +778,13 @@
696 778 $result['failed'][] = $original_post_id;
697 779
698 780 $this->output['errors'][] = $error;
699 781
700 - continue;
782 + if ( 'attachment' === $postdata['post_type'] ) {
783 + do_action( 'templately_import.process_post', $post, $result, $this );
784 + }
785 +
786 + return $result;
701 787 }
702 788
703 789 $result['succeed'][ $original_post_id ] = $post_id;
704 790
@@ -852,13 +938,15 @@
852 938 }
853 939 }
854 940
855 941 do_action( 'templately_import.process_post', $post, $result, $this );
856 - }
857 942
943 + return $result;
944 + }, $backup_key); //, true
945 +
858 946 unset( $this->posts );
859 947
860 - return $result;
948 + return $results;
861 949 }
862 950
863 951 /**
864 952 * Attempt to create a new menu item from import data
@@ -1039,9 +1127,9 @@
1039 1127 * @param string $url URL to fetch attachment from
1040 1128 *
1041 1129 * @return int|WP_Error Post ID on success, WP_Error otherwise
1042 1130 */
1043 - public function process_attachment( $post, $url, $sizes = [] ) {
1131 + public function process_attachment( $post, $url, $sizes = [], $original_post_id = null ) {
1044 1132 if ( ! $this->fetch_attachments ) {
1045 1133 return new WP_Error( 'attachment_processing_error', esc_html__( 'Fetching attachments is not enabled', 'elementor' ) );
1046 1134 }
1047 1135 if ( ! function_exists( 'wp_crop_image' ) ) {
@@ -1052,10 +1140,24 @@
1052 1140 $url = rtrim( $this->base_url, '/' ) . $url;
1053 1141 }
1054 1142
1055 1143 if($saved_image = $this->get_saved_image($url)){
1056 - $this->url_remap[ $url ] = wp_get_attachment_url( $saved_image );
1057 - $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension(wp_get_attachment_url( $saved_image ));
1144 + // $this->url_remap[ $url ] = wp_get_attachment_url( $saved_image );
1145 + // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension(wp_get_attachment_url( $saved_image ));
1146 + $upload_url = set_url_scheme( wp_get_attachment_url( $saved_image ) );
1147 + $this->set_url_map($url, $upload_url, true);
1148 +
1149 + if(!empty($post['original_attachment_url']) && !$this->get_saved_image($post['original_attachment_url'])){
1150 + add_post_meta( $saved_image, '_elementor_source_image_hash', sha1( $post['original_attachment_url'] ) );
1151 + self::$_replace_image_ids[ sha1( $post['original_attachment_url'] ) ] = $post_id;
1152 + }
1153 +
1154 + $full_size_path = get_attached_file($saved_image);
1155 + $metadata = wp_get_attachment_metadata($saved_image);
1156 + $updated_metadata = $this->import_sizes($sizes, $metadata, $full_size_path, $saved_image);
1157 + if ($updated_metadata !== false) {
1158 + wp_update_attachment_metadata( $saved_image, $updated_metadata );
1159 + }
1058 1160 return $saved_image;
1059 1161 }
1060 1162
1061 1163 // Check if the URL is from the wp-includes/images directory
@@ -1077,10 +1179,24 @@
1077 1179 // Move the file to the uploads dir.
1078 1180 $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1079 1181 $file_name = wp_unique_filename( $upload_dir['path'], $file_name );
1080 1182 $dest_file = $upload_dir['path'] . "/$file_name";
1081 - $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1183 + $start = microtime(true);
1082 1184
1185 + $upload = apply_filters( 'templately_import_copy_attachment', null, $original_post_id, $dest_file, $upload_dir );
1186 + if ( null === $upload ) {
1187 + $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1188 + }
1189 +
1190 + // Normalize URL scheme to match the current site scheme (fixes HTTP URLs on HTTPS multisites).
1191 + if ( ! is_wp_error( $upload ) && ! empty( $upload['url'] ) ) {
1192 + $upload['url'] = set_url_scheme( $upload['url'] );
1193 + }
1194 +
1195 + $end = microtime(true);
1196 + $duration = $end - $start;
1197 + error_log('Duration: ' . $duration);
1198 +
1083 1199 if ( is_wp_error( $upload ) ) {
1084 1200 return $upload;
1085 1201 }
1086 1202
@@ -1090,14 +1206,19 @@
1090 1206 } else {
1091 1207 return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'elementor' ) );
1092 1208 }
1093 1209
1094 - $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1210 + // $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1211 + // $this->set_url_map($post['guid'], $upload['url']);
1095 1212 $post['guid'] = $upload['url'];
1096 1213
1097 1214 // As per wp-admin/includes/upload.php.
1098 1215 $post_id = wp_insert_attachment( $post, $upload['file'] );
1099 1216
1217 + if(is_wp_error($post_id)){
1218 + return $post_id;
1219 + }
1220 +
1100 1221 $this->update_post_meta( $post_id );
1101 1222
1102 1223 // Generate attachment metadata
1103 1224 $metadata = wp_generate_attachment_metadata( $post_id, $upload['file'] );
@@ -1104,21 +1225,46 @@
1104 1225
1105 1226 // error_log('Metadata: ' . print_r($metadata, true));
1106 1227
1107 1228 // For gutenberg pages
1108 - $metadata = $this->import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id);
1229 + $updated_metadata = $this->import_sizes($sizes, $metadata, $upload['file'], $post_id);
1109 1230
1110 1231 // error_log('Metadata: ' . print_r($metadata, true));
1111 - wp_update_attachment_metadata( $post_id, $metadata );
1232 + if ($updated_metadata !== false) {
1233 + wp_update_attachment_metadata( $post_id, $updated_metadata );
1234 + } else {
1235 + wp_update_attachment_metadata( $post_id, $metadata );
1236 + }
1112 1237
1113 1238 // @todo: add missing image sizes
1239 + if(defined('TEMPLATELY_DEV') && TEMPLATELY_DEV){
1240 + update_post_meta( $post_id, '_templately_original_id', $original_post_id );
1241 + update_post_meta( $post_id, '_templately_original_url', $url );
1114 1242
1243 + if(!empty($post['original_attachment_url'])){
1244 + update_post_meta( $post_id, '_templately_demo_url', $post['original_attachment_url'] );
1245 + }
1246 + }
1247 +
1115 1248 update_post_meta( $post_id, '_elementor_source_image_hash', sha1( $url ) );
1116 1249 self::$_replace_image_ids[ sha1( $url ) ] = $post_id;
1117 1250
1251 + // add a second hash for original demo url
1252 + // if user is replacing image.
1253 + // so we can also match original demo url to new image
1254 + if(!empty($post['original_attachment_url'])){
1255 + $hash_meta_id = add_post_meta( $post_id, '_elementor_source_image_hash', sha1( $post['original_attachment_url'] ) );
1256 + add_post_meta( $post_id, '_templately_image_hash_meta_id', $hash_meta_id );
1257 + self::$_replace_image_ids[ sha1( $post['original_attachment_url'] ) ] = $post_id;
1258 + }
1259 +
1118 1260 // Remap resized image URLs, works by stripping the extension and remapping the URL stub.
1119 1261 if ( preg_match( '!^image/!', $info['type'] ) ) {
1120 - $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1262 + // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1263 + $this->set_url_map($url, $upload['url'], true);
1264 + if(!empty($post['original_attachment_url'])){
1265 + $this->set_url_map($post['original_attachment_url'], $upload['url'], true);
1266 + }
1121 1267 }
1122 1268
1123 1269 return $post_id;
1124 1270 }
@@ -1129,8 +1275,17 @@
1129 1275
1130 1276 return $parts['dirname'] . '/' . $name;
1131 1277 }
1132 1278
1279 + public function set_url_map($original_url, $new_url, $remove_extension = false){
1280 + $this->url_remap[ $original_url ] = $new_url;
1281 + if($remove_extension){
1282 + $original_url = $this->remove_extension($original_url);
1283 + $new_url = $this->remove_extension($new_url);
1284 + $this->url_remap[ $original_url ] = $new_url;
1285 + }
1286 + }
1287 +
1133 1288 /**
1134 1289 * Attempt to download a remote file attachment
1135 1290 *
1136 1291 * @param string $url URL of item to fetch
@@ -1179,10 +1334,8 @@
1179 1334
1180 1335 // Make sure the fetch was successful.
1181 1336 if ( 200 !== $remote_response_code ) {
1182 1337 @unlink( $tmp_file_name );
1183 - Helper::log($url);
1184 - Helper::log($remote_response);
1185 1338 return new WP_Error( 'import_file_error', sprintf( /* translators: 1: HTTP error message, 2: HTTP error code. */ esc_html__( 'Remote server returned the following unexpected result: %1$s (%2$s)', 'elementor' ), get_status_header_desc( $remote_response_code ), esc_html( $remote_response_code ) ) );
1186 1339 }
1187 1340
1188 1341 $headers = wp_remote_retrieve_headers( $remote_response );
@@ -1269,12 +1422,12 @@
1269 1422 'error' => false,
1270 1423 ];
1271 1424
1272 1425 // Keep track of the old and new urls so we can substitute them later.
1273 - $this->url_remap[ $url ] = $upload['url'];
1426 + $this->set_url_map($url, $upload['url']);
1274 1427 // Keep track of the destination if the remote url is redirected somewhere else.
1275 1428 if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
1276 - $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1429 + $this->set_url_map($headers['x-final-location'], $upload['url']);
1277 1430 }
1278 1431
1279 1432 return $upload;
1280 1433 }
@@ -1288,9 +1441,9 @@
1288 1441 * @access private
1289 1442 *
1290 1443 * @param string $url The image URL.
1291 1444 *
1292 - * @return false|array New image ID or false.
1445 + * @return false|int New image ID or false.
1293 1446 */
1294 1447 private function get_saved_image( $url ) {
1295 1448 global $wpdb;
1296 1449
@@ -1311,9 +1464,9 @@
1311 1464 );
1312 1465
1313 1466 if ( $post_id ) {
1314 1467 self::$_replace_image_ids[ $hash ] = $post_id;
1315 - return $post_id;
1468 + return (int) $post_id;
1316 1469 }
1317 1470
1318 1471 return false;
1319 1472 }
@@ -1318,69 +1471,97 @@
1318 1471 return false;
1319 1472 }
1320 1473
1321 1474
1322 - public function extract_sizes($sizes) {
1323 - return array_reduce($sizes, function($carry, $url) {
1324 - if (preg_match('/-((\d+)x(\d+))\./', $url, $matches)) {
1325 - $carry[$matches[1]] = $url;
1326 - }
1327 - return $carry;
1328 - }, []);
1329 - }
1475 + public function import_sizes($sizes, $metadata, $full_size_file, $post_id) {
1476 + $metadata_modified = false;
1330 1477
1331 - public function size_exists_in_metadata($size_dimension, $metadata) {
1332 - foreach ($metadata['sizes'] as $size => $size_info) {
1333 - if (strpos($size_info['file'], $size_dimension) !== false) {
1334 - return true;
1335 - }
1336 - }
1337 - return false;
1338 - }
1478 + if (!empty($sizes)) {
1479 + do_action('templately_import.finalize_gutenberg_attachment', $post_id);
1339 1480
1340 - public function create_unique_destination_file($upload_file, $size_dimension) {
1341 - $destination_file = preg_replace('/(\.[^.]+)$/', '-' . $size_dimension . '$1', $upload_file);
1342 - $destination_dir = pathinfo($destination_file, PATHINFO_DIRNAME);
1343 - $destination_filename = pathinfo($destination_file, PATHINFO_BASENAME);
1344 - $unique_filename = wp_unique_filename($destination_dir, $destination_filename);
1345 - return $destination_dir . '/' . $unique_filename;
1346 - }
1481 + foreach ($sizes as $size_name => $size) {
1482 + $size_dimension = $size['width'] . 'x' . $size['height'];
1483 + $size_name = !is_string($size_name) ? $size_dimension : $size_name;
1484 + $unique_destination_file = $this->create_unique_destination_file($full_size_file, $size);
1485 + // check non cropped sizes. with dynamic height
1486 + if (!$this->size_exists_in_metadata(basename($unique_destination_file), $metadata)) {
1487 + if ($unique_destination_file) {
1488 + $missing_size = $this->generate_missing_size_from_full($full_size_file, $unique_destination_file, $size);
1489 + if ($missing_size && !is_wp_error($missing_size)) {
1490 + unset($missing_size['path']);
1491 + $metadata['sizes'][$size_name] = $missing_size;
1492 + $metadata_modified = true;
1493 + do_action('templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension);
1494 + }
1495 + }
1496 + }
1497 + }
1498 + }
1347 1499
1348 - public function create_size_array($destination_file, $size_dimension) {
1349 - list($width, $height) = explode('x', $size_dimension);
1350 - return array(
1351 - 'file' => basename($destination_file),
1352 - 'width' => $width,
1353 - 'height' => $height,
1354 - 'mime-type' => wp_check_filetype($destination_file)['type'],
1355 - 'filesize' => filesize($destination_file),
1356 - 'resized' => false,
1357 - );
1358 - }
1500 + // Only return metadata if new sizes were actually added
1501 + return $metadata_modified ? $metadata : false;
1502 + }
1359 1503
1360 - public function import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id) {
1361 - if (!empty($sizes)) {
1362 - do_action( 'templately_import.finalize_gutenberg_attachment', $post_id );
1504 + public function generate_missing_size_from_full($full_size_file, $destination_file, $size) {
1505 + // Generate the missing size from the full-size image
1506 + $editor = wp_get_image_editor($full_size_file);
1507 + if (is_wp_error($editor)) {
1508 + return $editor;
1509 + }
1363 1510
1364 - $size_dimensions = $this->extract_sizes($sizes);
1365 - $size_dimensions = array_filter($size_dimensions);
1511 + $resized = $editor->resize($size['width'], $size['height'], true);
1512 + if (is_wp_error($resized)) {
1513 + return $resized;
1514 + }
1366 1515
1367 - foreach ($size_dimensions as $size_dimension => $__url) {
1368 - if (!$this->size_exists_in_metadata($size_dimension, $metadata)) {
1369 - $unique_destination_file = $this->create_unique_destination_file($upload['file'], $size_dimension);
1370 - $missing_size = $this->fetch_remote_file($__url, $unique_destination_file, $upload_dir);
1516 + $saved = $editor->save($destination_file);
1517 + if (is_wp_error($saved)) {
1518 + return $saved;
1519 + }
1371 1520
1372 - if($missing_size && !is_wp_error($missing_size)) {
1373 - $metadata['sizes'][$size_dimension] = $this->create_size_array($unique_destination_file, $size_dimension);
1374 - do_action( 'templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension );
1375 - }
1376 - }
1377 - }
1521 + return $saved;
1522 + }
1378 1523
1379 - }
1380 - return $metadata;
1381 - }
1524 + public function size_exists_in_metadata($size_file, $metadata) {
1525 + if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
1526 + foreach ($metadata['sizes'] as $size_info) {
1527 + if ($size_info['file'] == $size_file) {
1528 + return true;
1529 + }
1530 + }
1531 + }
1532 + return false;
1533 + }
1382 1534
1535 + public function create_unique_destination_file($full_size_file, $size) {
1536 + $pathinfo = pathinfo($full_size_file);
1537 + $directory = $pathinfo['dirname'];
1538 + $filename = $pathinfo['filename'];
1539 + $extension = $pathinfo['extension'];
1540 +
1541 + $destination_file = $directory . '/' . $filename . '-' . $size['width'] . 'x' . $size['height'] . '.' . $extension;
1542 +
1543 + // Skip if the file already exists
1544 + if (file_exists($destination_file)) {
1545 + // return false;
1546 + }
1547 +
1548 + return $destination_file;
1549 + }
1550 +
1551 + public function create_size_array($destination_file, $size_dimension) {
1552 + list($width, $height) = explode('x', $size_dimension);
1553 + return array(
1554 + 'file' => basename($destination_file),
1555 + 'width' => $width,
1556 + 'height' => $height,
1557 + 'mime-type' => wp_check_filetype($destination_file)['type'],
1558 + 'filesize' => filesize($destination_file),
1559 + 'resized' => false,
1560 + );
1561 + }
1562 +
1563 +
1383 1564 /**
1384 1565 * Attempt to associate posts and menu items with previously missing parents
1385 1566 *
1386 1567 * An imported post's parent may not have been imported when it was first created
@@ -1498,9 +1679,9 @@
1498 1679 */
1499 1680 private function is_valid_meta_key( $key ) {
1500 1681 // Skip attachment metadata since we'll regenerate it from scratch.
1501 1682 // Skip _edit_lock as not relevant for import
1502 - if ( in_array( $key, [ '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ] ) ) {
1683 + if ( in_array( $key, [ '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock', '_elementor_source_image_hash', 'sm_cloud' ] ) ) {
1503 1684 return false;
1504 1685 }
1505 1686
1506 1687 return $key;
@@ -1547,9 +1728,9 @@
1547 1728 * @param $post_id
1548 1729 *
1549 1730 * @return void
1550 1731 */
1551 - private function update_post_meta( $post_id ) {
1732 + public function update_post_meta( $post_id ) {
1552 1733 foreach ( $this->posts_meta as $meta_key => $meta_value ) {
1553 1734 update_post_meta( $post_id, $meta_key, $meta_value );
1554 1735 }
1555 1736 }
@@ -1560,8 +1741,23 @@
1560 1741 return $this->output;
1561 1742 }
1562 1743
1563 1744 /**
1745 + * Register Templately with Jetpack Sync's known importers.
1746 + *
1747 + * This filter callback adds Templately to Jetpack's list of known importers,
1748 + * ensuring that 'templately' is sent to WordPress.com instead of the full class name.
1749 + * This provides cleaner analytics data and better tracking.
1750 + *
1751 + * @param array $known_importers Array of known importers with class names as keys and friendly names as values.
1752 + * @return array Modified array of known importers.
1753 + */
1754 + public function register_jetpack_importer( $known_importers ) {
1755 + $known_importers[ __CLASS__ ] = 'templately';
1756 + return $known_importers;
1757 + }
1758 +
1759 + /**
1564 1760 * @param $file
1565 1761 * @param array $args
1566 1762 */
1567 1763 public function __construct( $file, array $args = [] ) {
@@ -1566,11 +1762,24 @@
1566 1762 */
1567 1763 public function __construct( $file, array $args = [] ) {
1568 1764 parent::__construct();
1569 1765
1570 - $this->requested_file_path = $file;
1571 - $this->args = $args;
1766 + $this->args = $args;
1767 + $this->session_id = $args['session_id'];
1572 1768
1769 + if ( ! empty( $args['json'] ) ) {
1770 + $this->json = $args['json'];
1771 + }
1772 +
1773 + if ( ! empty( $args['origin'] ) ) {
1774 + $this->origin = $args['origin'];
1775 + }
1776 +
1777 + if ( ! empty( $file ) ) {
1778 + $this->requested_file_path = $file;
1779 + $this->import_data_key = 'wp_importer_attributes_' . md5($this->requested_file_path);
1780 + }
1781 +
1573 1782 if ( ! empty( $this->args['fetch_attachments'] ) ) {
1574 1783 $this->fetch_attachments = true;
1575 1784 }
1576 1785
@@ -1592,6 +1801,9 @@
1592 1801
1593 1802 if ( ! empty( $this->args['terms_meta'] ) ) {
1594 1803 $this->terms_meta = $this->args['terms_meta'];
1595 1804 }
1805 +
1806 + // Register with Jetpack Sync for better analytics tracking.
1807 + add_filter( 'jetpack_sync_known_importers', [ $this, 'register_jetpack_importer' ] );
1596 1808 }
1597 1809 }