PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.4.9
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.4.9
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 +286 -89 3.1.03.4.9 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',
@@ -110,8 +123,25 @@
110 123 private $terms_meta = [];
111 124
112 125 public static $_replace_image_ids = [];
113 126
127 +
128 + public $backup_attributes = [
129 + 'output',
130 + 'url_remap',
131 + '_replace_image_ids',
132 + 'menu_item_orphans',
133 + 'processed_menu_items',
134 + 'post_orphans',
135 + 'processed_posts',
136 + 'featured_images',
137 + 'mapped_terms_slug',
138 + 'processed_terms',
139 + 'processed_authors',
140 + 'author_mapping',
141 + ];
142 +
143 +
114 144 /**
115 145 * Parses filename from a Content-Disposition header value.
116 146 *
117 147 * As per RFC6266:
@@ -287,9 +317,10 @@
287 317
288 318 wp_defer_term_counting( true );
289 319 wp_defer_comment_counting( true );
290 320
291 - do_action( 'import_start', $this );
321 + do_action( 'import_start' );
322 + do_action( 'templately_import_start', $this );
292 323
293 324 return true;
294 325 }
295 326
@@ -353,8 +384,14 @@
353 384 if ( ! isset( $this->args['imported_authors'] ) ) {
354 385 return;
355 386 }
356 387
388 +
389 + $processed_templates = $this->get_progress([], $this->import_data_key);
390 + if (!empty($processed_templates)) {
391 + return;
392 + }
393 +
357 394 $create_users = apply_filters( 'import_allow_create_users', self::DEFAULT_ALLOW_CREATE_USERS );
358 395
359 396 foreach ( (array) $this->args['imported_authors'] as $i => $old_login ) {
360 397 // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
@@ -409,8 +446,10 @@
409 446 }
410 447 $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
411 448 }
412 449 }
450 +
451 + $this->update_progress( true, null, $this->import_data_key );
413 452 }
414 453
415 454 /**
416 455 * Create new terms based on import information
@@ -424,8 +463,14 @@
424 463 'succeed' => [],
425 464 'failed' => [],
426 465 ];
427 466
467 + $processed_templates = $this->get_progress([], "wp_import_terms_" . $this->import_data_key);
468 + if (!empty($processed_templates)) {
469 + $result = $this->get_result([], "wp_import_terms_" . $this->import_data_key);
470 + return $result;
471 + }
472 +
428 473 $this->terms = apply_filters( 'wp_import_terms', $this->terms );
429 474 if ( empty( $this->terms ) ) {
430 475 return $result;
431 476 }
@@ -505,8 +550,10 @@
505 550 }
506 551
507 552 unset( $this->terms );
508 553
554 + // Add the template to the processed templates and update the session data
555 + $this->update_progress( true, $result, "wp_import_terms_" . $this->import_data_key);
509 556 return $result;
510 557 }
511 558
512 559 /**
@@ -576,42 +623,59 @@
576 623 *
577 624 * @return array the ids of succeed/failed imported posts.
578 625 */
579 626 private function process_posts(): array {
580 - $result = [
581 - 'succeed' => [],
582 - 'failed' => [],
583 - ];
627 + $backup_key = "wp_import_post_" . $this->import_data_key;
584 628
585 629 $this->posts = apply_filters( 'wp_import_posts', $this->posts );
586 630
587 - foreach ( $this->posts as $post ) {
588 - $post = apply_filters( 'wp_import_post_data_raw', $post );
631 + $results = $this->loop( $this->posts, function($key, $post, $result ) {
589 632
633 + $result = !empty($result) ? $result : [
634 + 'succeed' => [],
635 + 'failed' => [],
636 + ];
637 +
638 + $original_post_id = $post['post_id'];
639 + $post = apply_filters( 'wp_import_post_data_raw', $post, $this );
640 +
641 + if(empty($post)){
642 + return $result;
643 + }
644 +
645 + if(!is_array($post) && is_numeric($post)){
646 + $result['succeed'][ $original_post_id ] = $post;
647 + return $result;
648 + }
649 +
590 650 if ( ! post_type_exists( $post['post_type'] ) ) {
591 651 /* translators: 1: Post title, 2: Post type. */
592 652 $this->output['errors'][] = sprintf( esc_html__( 'Failed to import %1$s: Invalid post type %2$s', 'elementor' ), $post['post_title'], $post['post_type'] );
593 653 do_action( 'wp_import_post_exists', $post );
594 - continue;
654 + return $result;
595 655 }
596 656
597 657 if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) {
598 - continue;
658 + return $result;
599 659 }
600 660
601 661 if ( 'auto-draft' === $post['status'] ) {
602 - continue;
662 + return $result;
603 663 }
604 664
665 + if(!empty($post['post_content']) && !empty($post['post_id'])){
666 + $post['post_content'] = Utils::import_and_replace_attachments($post['post_content'], $post['post_id']);
667 + }
668 +
605 669 if ( 'nav_menu_item' === $post['post_type'] ) {
606 670 $result['succeed'] += $this->process_menu_item( $post );
607 - continue;
671 + return $result;
608 672 }
609 673
610 674 if ( 'wp_navigation' === $post['post_type'] ) {
611 675 $processed = $this->process_navigation( $post );
612 676 if ( ! $processed ) {
613 - continue;
677 + return $result;
614 678 }
615 679 }
616 680
617 681 $post_type_object = get_post_type_object( $post['post_type'] );
@@ -651,9 +715,12 @@
651 715 'post_type' => $post['post_type'],
652 716 'post_password' => $post['post_password'],
653 717 ];
654 718
655 - $original_post_id = $post['post_id'];
719 + if(isset($post['original_attachment_url'])){
720 + $postdata['original_attachment_url'] = $post['original_attachment_url'];
721 + }
722 +
656 723 $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
657 724
658 725 $postdata = wp_slash( $postdata );
659 726
@@ -658,9 +725,9 @@
658 725 $postdata = wp_slash( $postdata );
659 726
660 727 if ( 'attachment' === $postdata['post_type'] ) {
661 728 $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid'];
662 -
729 + $attachment_sizes = [];
663 730 // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
664 731 // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
665 732 $postdata['upload_date'] = $post['post_date'];
666 733 if ( isset( $post['postmeta'] ) ) {
@@ -668,14 +735,19 @@
668 735 if ( '_wp_attached_file' === $meta['key'] ) {
669 736 if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) {
670 737 $postdata['upload_date'] = $matches[0];
671 738 }
672 - break;
739 + // break;
673 740 }
741 + else if ( '_wp_attachment_metadata' === $meta['key'] ) {
742 + $attachment_metadata = maybe_unserialize( $meta['value'] );
743 + $attachment_sizes = $attachment_metadata['sizes'] ?? [];
744 + // break;
745 + }
674 746 }
675 747 }
676 748
677 - $post_id = $this->process_attachment( $postdata, $remote_url );
749 + $post_id = $this->process_attachment( $postdata, $remote_url, $attachment_sizes, $original_post_id );
678 750 $comment_post_id = $post_id;
679 751 } else {
680 752 $post_id = wp_insert_post( $postdata, true );
681 753
@@ -696,9 +768,13 @@
696 768 $result['failed'][] = $original_post_id;
697 769
698 770 $this->output['errors'][] = $error;
699 771
700 - continue;
772 + if ( 'attachment' === $postdata['post_type'] ) {
773 + do_action( 'templately_import.process_post', $post, $result, $this );
774 + }
775 +
776 + return $result;
701 777 }
702 778
703 779 $result['succeed'][ $original_post_id ] = $post_id;
704 780
@@ -852,13 +928,15 @@
852 928 }
853 929 }
854 930
855 931 do_action( 'templately_import.process_post', $post, $result, $this );
856 - }
857 932
933 + return $result;
934 + }, $backup_key); //, true
935 +
858 936 unset( $this->posts );
859 937
860 - return $result;
938 + return $results;
861 939 }
862 940
863 941 /**
864 942 * Attempt to create a new menu item from import data
@@ -1039,9 +1117,9 @@
1039 1117 * @param string $url URL to fetch attachment from
1040 1118 *
1041 1119 * @return int|WP_Error Post ID on success, WP_Error otherwise
1042 1120 */
1043 - public function process_attachment( $post, $url, $sizes = [] ) {
1121 + public function process_attachment( $post, $url, $sizes = [], $original_post_id = null ) {
1044 1122 if ( ! $this->fetch_attachments ) {
1045 1123 return new WP_Error( 'attachment_processing_error', esc_html__( 'Fetching attachments is not enabled', 'elementor' ) );
1046 1124 }
1047 1125 if ( ! function_exists( 'wp_crop_image' ) ) {
@@ -1052,10 +1130,24 @@
1052 1130 $url = rtrim( $this->base_url, '/' ) . $url;
1053 1131 }
1054 1132
1055 1133 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 ));
1134 + // $this->url_remap[ $url ] = wp_get_attachment_url( $saved_image );
1135 + // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension(wp_get_attachment_url( $saved_image ));
1136 + $upload_url = wp_get_attachment_url( $saved_image );
1137 + $this->set_url_map($url, $upload_url, true);
1138 +
1139 + if(!empty($post['original_attachment_url']) && !$this->get_saved_image($post['original_attachment_url'])){
1140 + add_post_meta( $saved_image, '_elementor_source_image_hash', sha1( $post['original_attachment_url'] ) );
1141 + self::$_replace_image_ids[ sha1( $post['original_attachment_url'] ) ] = $post_id;
1142 + }
1143 +
1144 + $full_size_path = get_attached_file($saved_image);
1145 + $metadata = wp_get_attachment_metadata($saved_image);
1146 + $updated_metadata = $this->import_sizes($sizes, $metadata, $full_size_path, $saved_image);
1147 + if ($updated_metadata !== false) {
1148 + wp_update_attachment_metadata( $saved_image, $updated_metadata );
1149 + }
1058 1150 return $saved_image;
1059 1151 }
1060 1152
1061 1153 // Check if the URL is from the wp-includes/images directory
@@ -1077,10 +1169,19 @@
1077 1169 // Move the file to the uploads dir.
1078 1170 $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1079 1171 $file_name = wp_unique_filename( $upload_dir['path'], $file_name );
1080 1172 $dest_file = $upload_dir['path'] . "/$file_name";
1081 - $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1173 + $start = microtime(true);
1082 1174
1175 + $upload = apply_filters( 'templately_import_copy_attachment', null, $original_post_id, $dest_file, $upload_dir );
1176 + if ( null === $upload ) {
1177 + $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1178 + }
1179 +
1180 + $end = microtime(true);
1181 + $duration = $end - $start;
1182 + error_log('Duration: ' . $duration);
1183 +
1083 1184 if ( is_wp_error( $upload ) ) {
1084 1185 return $upload;
1085 1186 }
1086 1187
@@ -1090,14 +1191,19 @@
1090 1191 } else {
1091 1192 return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'elementor' ) );
1092 1193 }
1093 1194
1094 - $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1195 + // $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1196 + // $this->set_url_map($post['guid'], $upload['url']);
1095 1197 $post['guid'] = $upload['url'];
1096 1198
1097 1199 // As per wp-admin/includes/upload.php.
1098 1200 $post_id = wp_insert_attachment( $post, $upload['file'] );
1099 1201
1202 + if(is_wp_error($post_id)){
1203 + return $post_id;
1204 + }
1205 +
1100 1206 $this->update_post_meta( $post_id );
1101 1207
1102 1208 // Generate attachment metadata
1103 1209 $metadata = wp_generate_attachment_metadata( $post_id, $upload['file'] );
@@ -1104,21 +1210,46 @@
1104 1210
1105 1211 // error_log('Metadata: ' . print_r($metadata, true));
1106 1212
1107 1213 // For gutenberg pages
1108 - $metadata = $this->import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id);
1214 + $updated_metadata = $this->import_sizes($sizes, $metadata, $upload['file'], $post_id);
1109 1215
1110 1216 // error_log('Metadata: ' . print_r($metadata, true));
1111 - wp_update_attachment_metadata( $post_id, $metadata );
1217 + if ($updated_metadata !== false) {
1218 + wp_update_attachment_metadata( $post_id, $updated_metadata );
1219 + } else {
1220 + wp_update_attachment_metadata( $post_id, $metadata );
1221 + }
1112 1222
1113 1223 // @todo: add missing image sizes
1224 + if(defined('TEMPLATELY_DEV') && TEMPLATELY_DEV){
1225 + update_post_meta( $post_id, '_templately_original_id', $original_post_id );
1226 + update_post_meta( $post_id, '_templately_original_url', $url );
1114 1227
1228 + if(!empty($post['original_attachment_url'])){
1229 + update_post_meta( $post_id, '_templately_demo_url', $post['original_attachment_url'] );
1230 + }
1231 + }
1232 +
1115 1233 update_post_meta( $post_id, '_elementor_source_image_hash', sha1( $url ) );
1116 1234 self::$_replace_image_ids[ sha1( $url ) ] = $post_id;
1117 1235
1236 + // add a second hash for original demo url
1237 + // if user is replacing image.
1238 + // so we can also match original demo url to new image
1239 + if(!empty($post['original_attachment_url'])){
1240 + $hash_meta_id = add_post_meta( $post_id, '_elementor_source_image_hash', sha1( $post['original_attachment_url'] ) );
1241 + add_post_meta( $post_id, '_templately_image_hash_meta_id', $hash_meta_id );
1242 + self::$_replace_image_ids[ sha1( $post['original_attachment_url'] ) ] = $post_id;
1243 + }
1244 +
1118 1245 // Remap resized image URLs, works by stripping the extension and remapping the URL stub.
1119 1246 if ( preg_match( '!^image/!', $info['type'] ) ) {
1120 - $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1247 + // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1248 + $this->set_url_map($url, $upload['url'], true);
1249 + if(!empty($post['original_attachment_url'])){
1250 + $this->set_url_map($post['original_attachment_url'], $upload['url'], true);
1251 + }
1121 1252 }
1122 1253
1123 1254 return $post_id;
1124 1255 }
@@ -1129,8 +1260,17 @@
1129 1260
1130 1261 return $parts['dirname'] . '/' . $name;
1131 1262 }
1132 1263
1264 + public function set_url_map($original_url, $new_url, $remove_extension = false){
1265 + $this->url_remap[ $original_url ] = $new_url;
1266 + if($remove_extension){
1267 + $original_url = $this->remove_extension($original_url);
1268 + $new_url = $this->remove_extension($new_url);
1269 + $this->url_remap[ $original_url ] = $new_url;
1270 + }
1271 + }
1272 +
1133 1273 /**
1134 1274 * Attempt to download a remote file attachment
1135 1275 *
1136 1276 * @param string $url URL of item to fetch
@@ -1179,10 +1319,8 @@
1179 1319
1180 1320 // Make sure the fetch was successful.
1181 1321 if ( 200 !== $remote_response_code ) {
1182 1322 @unlink( $tmp_file_name );
1183 - Helper::log($url);
1184 - Helper::log($remote_response);
1185 1323 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 1324 }
1187 1325
1188 1326 $headers = wp_remote_retrieve_headers( $remote_response );
@@ -1269,12 +1407,12 @@
1269 1407 'error' => false,
1270 1408 ];
1271 1409
1272 1410 // Keep track of the old and new urls so we can substitute them later.
1273 - $this->url_remap[ $url ] = $upload['url'];
1411 + $this->set_url_map($url, $upload['url']);
1274 1412 // Keep track of the destination if the remote url is redirected somewhere else.
1275 1413 if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
1276 - $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1414 + $this->set_url_map($headers['x-final-location'], $upload['url']);
1277 1415 }
1278 1416
1279 1417 return $upload;
1280 1418 }
@@ -1288,9 +1426,9 @@
1288 1426 * @access private
1289 1427 *
1290 1428 * @param string $url The image URL.
1291 1429 *
1292 - * @return false|array New image ID or false.
1430 + * @return false|int New image ID or false.
1293 1431 */
1294 1432 private function get_saved_image( $url ) {
1295 1433 global $wpdb;
1296 1434
@@ -1311,9 +1449,9 @@
1311 1449 );
1312 1450
1313 1451 if ( $post_id ) {
1314 1452 self::$_replace_image_ids[ $hash ] = $post_id;
1315 - return $post_id;
1453 + return (int) $post_id;
1316 1454 }
1317 1455
1318 1456 return false;
1319 1457 }
@@ -1318,69 +1456,97 @@
1318 1456 return false;
1319 1457 }
1320 1458
1321 1459
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 - }
1460 + public function import_sizes($sizes, $metadata, $full_size_file, $post_id) {
1461 + $metadata_modified = false;
1330 1462
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 - }
1463 + if (!empty($sizes)) {
1464 + do_action('templately_import.finalize_gutenberg_attachment', $post_id);
1339 1465
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 - }
1466 + foreach ($sizes as $size_name => $size) {
1467 + $size_dimension = $size['width'] . 'x' . $size['height'];
1468 + $size_name = !is_string($size_name) ? $size_dimension : $size_name;
1469 + $unique_destination_file = $this->create_unique_destination_file($full_size_file, $size);
1470 + // check non cropped sizes. with dynamic height
1471 + if (!$this->size_exists_in_metadata(basename($unique_destination_file), $metadata)) {
1472 + if ($unique_destination_file) {
1473 + $missing_size = $this->generate_missing_size_from_full($full_size_file, $unique_destination_file, $size);
1474 + if ($missing_size && !is_wp_error($missing_size)) {
1475 + unset($missing_size['path']);
1476 + $metadata['sizes'][$size_name] = $missing_size;
1477 + $metadata_modified = true;
1478 + do_action('templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension);
1479 + }
1480 + }
1481 + }
1482 + }
1483 + }
1347 1484
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 - }
1485 + // Only return metadata if new sizes were actually added
1486 + return $metadata_modified ? $metadata : false;
1487 + }
1359 1488
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 );
1489 + public function generate_missing_size_from_full($full_size_file, $destination_file, $size) {
1490 + // Generate the missing size from the full-size image
1491 + $editor = wp_get_image_editor($full_size_file);
1492 + if (is_wp_error($editor)) {
1493 + return $editor;
1494 + }
1363 1495
1364 - $size_dimensions = $this->extract_sizes($sizes);
1365 - $size_dimensions = array_filter($size_dimensions);
1496 + $resized = $editor->resize($size['width'], $size['height'], true);
1497 + if (is_wp_error($resized)) {
1498 + return $resized;
1499 + }
1366 1500
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);
1501 + $saved = $editor->save($destination_file);
1502 + if (is_wp_error($saved)) {
1503 + return $saved;
1504 + }
1371 1505
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 - }
1506 + return $saved;
1507 + }
1378 1508
1379 - }
1380 - return $metadata;
1381 - }
1509 + public function size_exists_in_metadata($size_file, $metadata) {
1510 + if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
1511 + foreach ($metadata['sizes'] as $size_info) {
1512 + if ($size_info['file'] == $size_file) {
1513 + return true;
1514 + }
1515 + }
1516 + }
1517 + return false;
1518 + }
1382 1519
1520 + public function create_unique_destination_file($full_size_file, $size) {
1521 + $pathinfo = pathinfo($full_size_file);
1522 + $directory = $pathinfo['dirname'];
1523 + $filename = $pathinfo['filename'];
1524 + $extension = $pathinfo['extension'];
1525 +
1526 + $destination_file = $directory . '/' . $filename . '-' . $size['width'] . 'x' . $size['height'] . '.' . $extension;
1527 +
1528 + // Skip if the file already exists
1529 + if (file_exists($destination_file)) {
1530 + // return false;
1531 + }
1532 +
1533 + return $destination_file;
1534 + }
1535 +
1536 + public function create_size_array($destination_file, $size_dimension) {
1537 + list($width, $height) = explode('x', $size_dimension);
1538 + return array(
1539 + 'file' => basename($destination_file),
1540 + 'width' => $width,
1541 + 'height' => $height,
1542 + 'mime-type' => wp_check_filetype($destination_file)['type'],
1543 + 'filesize' => filesize($destination_file),
1544 + 'resized' => false,
1545 + );
1546 + }
1547 +
1548 +
1383 1549 /**
1384 1550 * Attempt to associate posts and menu items with previously missing parents
1385 1551 *
1386 1552 * An imported post's parent may not have been imported when it was first created
@@ -1498,9 +1664,9 @@
1498 1664 */
1499 1665 private function is_valid_meta_key( $key ) {
1500 1666 // Skip attachment metadata since we'll regenerate it from scratch.
1501 1667 // Skip _edit_lock as not relevant for import
1502 - if ( in_array( $key, [ '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ] ) ) {
1668 + if ( in_array( $key, [ '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock', '_elementor_source_image_hash', 'sm_cloud' ] ) ) {
1503 1669 return false;
1504 1670 }
1505 1671
1506 1672 return $key;
@@ -1547,9 +1713,9 @@
1547 1713 * @param $post_id
1548 1714 *
1549 1715 * @return void
1550 1716 */
1551 - private function update_post_meta( $post_id ) {
1717 + public function update_post_meta( $post_id ) {
1552 1718 foreach ( $this->posts_meta as $meta_key => $meta_value ) {
1553 1719 update_post_meta( $post_id, $meta_key, $meta_value );
1554 1720 }
1555 1721 }
@@ -1560,8 +1726,23 @@
1560 1726 return $this->output;
1561 1727 }
1562 1728
1563 1729 /**
1730 + * Register Templately with Jetpack Sync's known importers.
1731 + *
1732 + * This filter callback adds Templately to Jetpack's list of known importers,
1733 + * ensuring that 'templately' is sent to WordPress.com instead of the full class name.
1734 + * This provides cleaner analytics data and better tracking.
1735 + *
1736 + * @param array $known_importers Array of known importers with class names as keys and friendly names as values.
1737 + * @return array Modified array of known importers.
1738 + */
1739 + public function register_jetpack_importer( $known_importers ) {
1740 + $known_importers[ __CLASS__ ] = 'templately';
1741 + return $known_importers;
1742 + }
1743 +
1744 + /**
1564 1745 * @param $file
1565 1746 * @param array $args
1566 1747 */
1567 1748 public function __construct( $file, array $args = [] ) {
@@ -1566,11 +1747,24 @@
1566 1747 */
1567 1748 public function __construct( $file, array $args = [] ) {
1568 1749 parent::__construct();
1569 1750
1570 - $this->requested_file_path = $file;
1571 - $this->args = $args;
1751 + $this->args = $args;
1752 + $this->session_id = $args['session_id'];
1572 1753
1754 + if ( ! empty( $args['json'] ) ) {
1755 + $this->json = $args['json'];
1756 + }
1757 +
1758 + if ( ! empty( $args['origin'] ) ) {
1759 + $this->origin = $args['origin'];
1760 + }
1761 +
1762 + if ( ! empty( $file ) ) {
1763 + $this->requested_file_path = $file;
1764 + $this->import_data_key = 'wp_importer_attributes_' . md5($this->requested_file_path);
1765 + }
1766 +
1573 1767 if ( ! empty( $this->args['fetch_attachments'] ) ) {
1574 1768 $this->fetch_attachments = true;
1575 1769 }
1576 1770
@@ -1592,6 +1786,9 @@
1592 1786
1593 1787 if ( ! empty( $this->args['terms_meta'] ) ) {
1594 1788 $this->terms_meta = $this->args['terms_meta'];
1595 1789 }
1790 +
1791 + // Register with Jetpack Sync for better analytics tracking.
1792 + add_filter( 'jetpack_sync_known_importers', [ $this, 'register_jetpack_importer' ] );
1596 1793 }
1597 1794 }