PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.3.3
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.3.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 +24 -160 3.7.13.3.3 View file →
@@ -87,18 +87,8 @@
87 87 * WXR attachment ID
88 88 */
89 89 private $id;
90 90
91 - /**
92 - * @var mixed
93 - */
94 - private $json;
95 -
96 - /**
97 - * @var string
98 - */
99 - private $session_id;
100 -
101 91 // Information to import from WXR file.
102 92 private $version;
103 93 private $authors = [];
104 94 public $posts = [];
@@ -119,10 +109,8 @@
119 109 private $menu_item_orphans = [];
120 110 private $mapped_terms_slug = [];
121 111
122 112 private $fetch_attachments = false;
123 - private $attachment_timeout = 300;
124 - private $attachment_retry_count = 3;
125 113 private $featured_images = [];
126 114
127 115 /**
128 116 * @var array[] [meta_key => meta_value] Meta value that should be set for every imported post.
@@ -329,10 +317,9 @@
329 317
330 318 wp_defer_term_counting( true );
331 319 wp_defer_comment_counting( true );
332 320
333 - do_action( 'import_start' );
334 - do_action( 'templately_import_start', $this );
321 + do_action( 'import_start', $this );
335 322
336 323 return true;
337 324 }
338 325
@@ -397,9 +384,9 @@
397 384 return;
398 385 }
399 386
400 387
401 - $processed_templates = $this->get_loop_result([], $this->import_data_key);
388 + $processed_templates = $this->get_progress([], $this->import_data_key);
402 389 if (!empty($processed_templates)) {
403 390 return;
404 391 }
405 392
@@ -459,9 +446,9 @@
459 446 $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
460 447 }
461 448 }
462 449
463 - $this->set_loop_result( true, $this->import_data_key );
450 + $this->update_progress( true, null, $this->import_data_key );
464 451 }
465 452
466 453 /**
467 454 * Create new terms based on import information
@@ -475,11 +462,11 @@
475 462 'succeed' => [],
476 463 'failed' => [],
477 464 ];
478 465
479 - $processed_templates = $this->get_loop_result([], "wp_import_terms_" . $this->import_data_key);
466 + $processed_templates = $this->get_progress([], "wp_import_terms_" . $this->import_data_key);
480 467 if (!empty($processed_templates)) {
481 - $result = $this->get_loop_result([], "wp_import_terms_" . $this->import_data_key);
468 + $result = $this->get_result([], "wp_import_terms_" . $this->import_data_key);
482 469 return $result;
483 470 }
484 471
485 472 $this->terms = apply_filters( 'wp_import_terms', $this->terms );
@@ -563,9 +550,9 @@
563 550
564 551 unset( $this->terms );
565 552
566 553 // Add the template to the processed templates and update the session data
567 - $this->set_loop_result( $result, "wp_import_terms_" . $this->import_data_key);
554 + $this->update_progress( true, $result, "wp_import_terms_" . $this->import_data_key);
568 555 return $result;
569 556 }
570 557
571 558 /**
@@ -645,21 +632,10 @@
645 632 $result = !empty($result) ? $result : [
646 633 'succeed' => [],
647 634 'failed' => [],
648 635 ];
636 + $post = apply_filters( 'wp_import_post_data_raw', $post );
649 637
650 - $original_post_id = $post['post_id'];
651 - $post = apply_filters( 'wp_import_post_data_raw', $post, $this );
652 -
653 - if(empty($post)){
654 - return $result;
655 - }
656 -
657 - if(!is_array($post) && is_numeric($post)){
658 - $result['succeed'][ $original_post_id ] = $post;
659 - return $result;
660 - }
661 -
662 638 if ( ! post_type_exists( $post['post_type'] ) ) {
663 639 /* translators: 1: Post title, 2: Post type. */
664 640 $this->output['errors'][] = sprintf( esc_html__( 'Failed to import %1$s: Invalid post type %2$s', 'elementor' ), $post['post_title'], $post['post_type'] );
665 641 do_action( 'wp_import_post_exists', $post );
@@ -727,12 +703,9 @@
727 703 'post_type' => $post['post_type'],
728 704 'post_password' => $post['post_password'],
729 705 ];
730 706
731 - if(isset($post['original_attachment_url'])){
732 - $postdata['original_attachment_url'] = $post['original_attachment_url'];
733 - }
734 -
707 + $original_post_id = $post['post_id'];
735 708 $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
736 709
737 710 $postdata = wp_slash( $postdata );
738 711
@@ -1142,40 +1115,15 @@
1142 1115 $url = rtrim( $this->base_url, '/' ) . $url;
1143 1116 }
1144 1117
1145 1118 if($saved_image = $this->get_saved_image($url)){
1146 - // $this->url_remap[ $url ] = wp_get_attachment_url( $saved_image );
1147 - // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension(wp_get_attachment_url( $saved_image ));
1148 - $upload_url = set_url_scheme( wp_get_attachment_url( $saved_image ) );
1149 - $this->set_url_map($url, $upload_url, true);
1119 + $this->url_remap[ $url ] = wp_get_attachment_url( $saved_image );
1120 + $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension(wp_get_attachment_url( $saved_image ));
1150 1121
1151 - // AI image replacement: the imported content still carries the ORIGINAL
1152 - // demo URL, so it must be remapped onto the replacement image here too.
1153 - // The fresh-upload branch below does this, but when the replacement
1154 - // image was already imported (a re-import, or the same stock photo
1155 - // reused) we land here instead — without the map the demo URL survives
1156 - // finalize and the pack's original images are silently kept.
1157 - if(!empty($post['original_attachment_url'])){
1158 - $this->set_url_map($post['original_attachment_url'], $upload_url, true);
1159 -
1160 - $original_hash = sha1( $post['original_attachment_url'] );
1161 -
1162 - // A stale hash from a previous import can still point the demo URL at
1163 - // the old, unreplaced attachment — re-point it at the replacement.
1164 - if( (int) $this->get_saved_image($post['original_attachment_url']) !== (int) $saved_image ){
1165 - $hash_meta_id = add_post_meta( $saved_image, '_elementor_source_image_hash', $original_hash );
1166 - add_post_meta( $saved_image, '_templately_image_hash_meta_id', $hash_meta_id );
1167 - }
1168 -
1169 - self::$_replace_image_ids[ $original_hash ] = (int) $saved_image;
1170 - }
1171 -
1172 1122 $full_size_path = get_attached_file($saved_image);
1173 1123 $metadata = wp_get_attachment_metadata($saved_image);
1174 - $updated_metadata = $this->import_sizes($sizes, $metadata, $full_size_path, $saved_image);
1175 - if ($updated_metadata !== false) {
1176 - wp_update_attachment_metadata( $saved_image, $updated_metadata );
1177 - }
1124 + $metadata = $this->import_sizes($sizes, $metadata, $full_size_path, $saved_image);
1125 + wp_update_attachment_metadata( $saved_image, $metadata );
1178 1126 return $saved_image;
1179 1127 }
1180 1128
1181 1129 // Check if the URL is from the wp-includes/images directory
@@ -1204,13 +1152,8 @@
1204 1152 if ( null === $upload ) {
1205 1153 $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1206 1154 }
1207 1155
1208 - // Normalize URL scheme to match the current site scheme (fixes HTTP URLs on HTTPS multisites).
1209 - if ( ! is_wp_error( $upload ) && ! empty( $upload['url'] ) ) {
1210 - $upload['url'] = set_url_scheme( $upload['url'] );
1211 - }
1212 -
1213 1156 $end = microtime(true);
1214 1157 $duration = $end - $start;
1215 1158 error_log('Duration: ' . $duration);
1216 1159
@@ -1224,10 +1167,9 @@
1224 1167 } else {
1225 1168 return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'elementor' ) );
1226 1169 }
1227 1170
1228 - // $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1229 - // $this->set_url_map($post['guid'], $upload['url']);
1171 + $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1230 1172 $post['guid'] = $upload['url'];
1231 1173
1232 1174 // As per wp-admin/includes/upload.php.
1233 1175 $post_id = wp_insert_attachment( $post, $upload['file'] );
@@ -1243,46 +1185,21 @@
1243 1185
1244 1186 // error_log('Metadata: ' . print_r($metadata, true));
1245 1187
1246 1188 // For gutenberg pages
1247 - $updated_metadata = $this->import_sizes($sizes, $metadata, $upload['file'], $post_id);
1189 + $metadata = $this->import_sizes($sizes, $metadata, $upload['file'], $post_id);
1248 1190
1249 1191 // error_log('Metadata: ' . print_r($metadata, true));
1250 - if ($updated_metadata !== false) {
1251 - wp_update_attachment_metadata( $post_id, $updated_metadata );
1252 - } else {
1253 - wp_update_attachment_metadata( $post_id, $metadata );
1254 - }
1192 + wp_update_attachment_metadata( $post_id, $metadata );
1255 1193
1256 1194 // @todo: add missing image sizes
1257 - if(defined('TEMPLATELY_DEV') && TEMPLATELY_DEV){
1258 - update_post_meta( $post_id, '_templately_original_id', $original_post_id );
1259 - update_post_meta( $post_id, '_templately_original_url', $url );
1260 1195
1261 - if(!empty($post['original_attachment_url'])){
1262 - update_post_meta( $post_id, '_templately_demo_url', $post['original_attachment_url'] );
1263 - }
1264 - }
1265 -
1266 1196 update_post_meta( $post_id, '_elementor_source_image_hash', sha1( $url ) );
1267 1197 self::$_replace_image_ids[ sha1( $url ) ] = $post_id;
1268 1198
1269 - // add a second hash for original demo url
1270 - // if user is replacing image.
1271 - // so we can also match original demo url to new image
1272 - if(!empty($post['original_attachment_url'])){
1273 - $hash_meta_id = add_post_meta( $post_id, '_elementor_source_image_hash', sha1( $post['original_attachment_url'] ) );
1274 - add_post_meta( $post_id, '_templately_image_hash_meta_id', $hash_meta_id );
1275 - self::$_replace_image_ids[ sha1( $post['original_attachment_url'] ) ] = $post_id;
1276 - }
1277 -
1278 1199 // Remap resized image URLs, works by stripping the extension and remapping the URL stub.
1279 1200 if ( preg_match( '!^image/!', $info['type'] ) ) {
1280 - // $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1281 - $this->set_url_map($url, $upload['url'], true);
1282 - if(!empty($post['original_attachment_url'])){
1283 - $this->set_url_map($post['original_attachment_url'], $upload['url'], true);
1284 - }
1201 + $this->url_remap[ $this->remove_extension($url) ] = $this->remove_extension($upload['url']);
1285 1202 }
1286 1203
1287 1204 return $post_id;
1288 1205 }
@@ -1293,17 +1210,8 @@
1293 1210
1294 1211 return $parts['dirname'] . '/' . $name;
1295 1212 }
1296 1213
1297 - public function set_url_map($original_url, $new_url, $remove_extension = false){
1298 - $this->url_remap[ $original_url ] = $new_url;
1299 - if($remove_extension){
1300 - $original_url = $this->remove_extension($original_url);
1301 - $new_url = $this->remove_extension($new_url);
1302 - $this->url_remap[ $original_url ] = $new_url;
1303 - }
1304 - }
1305 -
1306 1214 /**
1307 1215 * Attempt to download a remote file attachment
1308 1216 *
1309 1217 * @param string $url URL of item to fetch
@@ -1326,13 +1234,13 @@
1326 1234 }
1327 1235
1328 1236 // Fetch the remote URL and write it to the placeholder file.
1329 1237 $attempt = 0;
1330 - $retry_count = $this->attachment_retry_count;
1238 + $retry_count = 3;
1331 1239 $remote_response = null;
1332 1240 do {
1333 1241 $remote_response = wp_safe_remote_get( $url, [
1334 - 'timeout' => $this->attachment_timeout,
1242 + 'timeout' => 300,
1335 1243 'stream' => true,
1336 1244 'filename' => $tmp_file_name,
1337 1245 'headers' => [
1338 1246 'Accept-Encoding' => 'identity',
@@ -1440,12 +1348,12 @@
1440 1348 'error' => false,
1441 1349 ];
1442 1350
1443 1351 // Keep track of the old and new urls so we can substitute them later.
1444 - $this->set_url_map($url, $upload['url']);
1352 + $this->url_remap[ $url ] = $upload['url'];
1445 1353 // Keep track of the destination if the remote url is redirected somewhere else.
1446 1354 if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
1447 - $this->set_url_map($headers['x-final-location'], $upload['url']);
1355 + $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1448 1356 }
1449 1357
1450 1358 return $upload;
1451 1359 }
@@ -1459,9 +1367,9 @@
1459 1367 * @access private
1460 1368 *
1461 1369 * @param string $url The image URL.
1462 1370 *
1463 - * @return false|int New image ID or false.
1371 + * @return false|array New image ID or false.
1464 1372 */
1465 1373 private function get_saved_image( $url ) {
1466 1374 global $wpdb;
1467 1375
@@ -1470,26 +1378,13 @@
1470 1378 if ( isset( self::$_replace_image_ids[ $hash ] ) ) {
1471 1379 return self::$_replace_image_ids[ $hash ];
1472 1380 }
1473 1381
1474 - // Newest row wins. A URL can be claimed by more than one attachment: an
1475 - // AI/customizer image replacement registers the ORIGINAL demo URL against
1476 - // the REPLACEMENT attachment (see process_attachment), while a previous
1477 - // plain import of the same pack already claimed that URL for the original
1478 - // image — and that older row is never cleaned up (clear_old_el_cache only
1479 - // tracks replacement hashes). Without the ordering the stale original wins
1480 - // and the replacement is silently ignored on every re-import.
1481 - //
1482 - // The static cache above short-circuits this, but the import is split
1483 - // across many requests (each SSE `continue` is a fresh PHP process), so
1484 - // the DB is the real source of truth for anything set in an earlier step.
1485 1382 $post_id = $wpdb->get_var(
1486 1383 $wpdb->prepare(
1487 1384 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
1488 1385 WHERE `meta_key` = \'_elementor_source_image_hash\'
1489 1386 AND `meta_value` = %s
1490 - ORDER BY `meta_id` DESC
1491 - LIMIT 1
1492 1387 ;',
1493 1388 $hash
1494 1389 )
1495 1390 );
@@ -1503,10 +1398,8 @@
1503 1398 }
1504 1399
1505 1400
1506 1401 public function import_sizes($sizes, $metadata, $full_size_file, $post_id) {
1507 - $metadata_modified = false;
1508 -
1509 1402 if (!empty($sizes)) {
1510 1403 do_action('templately_import.finalize_gutenberg_attachment', $post_id);
1511 1404
1512 1405 foreach ($sizes as $size_name => $size) {
@@ -1519,9 +1412,8 @@
1519 1412 $missing_size = $this->generate_missing_size_from_full($full_size_file, $unique_destination_file, $size);
1520 1413 if ($missing_size && !is_wp_error($missing_size)) {
1521 1414 unset($missing_size['path']);
1522 1415 $metadata['sizes'][$size_name] = $missing_size;
1523 - $metadata_modified = true;
1524 1416 do_action('templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension);
1525 1417 }
1526 1418 }
1527 1419 }
@@ -1526,11 +1418,9 @@
1526 1418 }
1527 1419 }
1528 1420 }
1529 1421 }
1530 -
1531 - // Only return metadata if new sizes were actually added
1532 - return $metadata_modified ? $metadata : false;
1422 + return $metadata;
1533 1423 }
1534 1424
1535 1425 public function generate_missing_size_from_full($full_size_file, $destination_file, $size) {
1536 1426 // Generate the missing size from the full-size image
@@ -1553,9 +1443,9 @@
1553 1443 }
1554 1444
1555 1445 public function size_exists_in_metadata($size_file, $metadata) {
1556 1446 if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
1557 - foreach ($metadata['sizes'] as $size_info) {
1447 + foreach ($metadata['sizes'] as $size => $size_info) {
1558 1448 if ($size_info['file'] == $size_file) {
1559 1449 return true;
1560 1450 }
1561 1451 }
@@ -1759,9 +1649,9 @@
1759 1649 * @param $post_id
1760 1650 *
1761 1651 * @return void
1762 1652 */
1763 - public function update_post_meta( $post_id ) {
1653 + private function update_post_meta( $post_id ) {
1764 1654 foreach ( $this->posts_meta as $meta_key => $meta_value ) {
1765 1655 update_post_meta( $post_id, $meta_key, $meta_value );
1766 1656 }
1767 1657 }
@@ -1772,23 +1662,8 @@
1772 1662 return $this->output;
1773 1663 }
1774 1664
1775 1665 /**
1776 - * Register Templately with Jetpack Sync's known importers.
1777 - *
1778 - * This filter callback adds Templately to Jetpack's list of known importers,
1779 - * ensuring that 'templately' is sent to WordPress.com instead of the full class name.
1780 - * This provides cleaner analytics data and better tracking.
1781 - *
1782 - * @param array $known_importers Array of known importers with class names as keys and friendly names as values.
1783 - * @return array Modified array of known importers.
1784 - */
1785 - public function register_jetpack_importer( $known_importers ) {
1786 - $known_importers[ __CLASS__ ] = 'templately';
1787 - return $known_importers;
1788 - }
1789 -
1790 - /**
1791 1666 * @param $file
1792 1667 * @param array $args
1793 1668 */
1794 1669 public function __construct( $file, array $args = [] ) {
@@ -1813,16 +1688,8 @@
1813 1688 if ( ! empty( $this->args['fetch_attachments'] ) ) {
1814 1689 $this->fetch_attachments = true;
1815 1690 }
1816 1691
1817 - if ( isset( $this->args['attachment_timeout'] ) && is_numeric( $this->args['attachment_timeout'] ) ) {
1818 - $this->attachment_timeout = max( 1, (int) $this->args['attachment_timeout'] );
1819 - }
1820 -
1821 - if ( isset( $this->args['attachment_retries'] ) && is_numeric( $this->args['attachment_retries'] ) ) {
1822 - $this->attachment_retry_count = max( 1, (int) $this->args['attachment_retries'] + 1 );
1823 - }
1824 -
1825 1692 if ( isset( $this->args['posts'] ) && is_array( $this->args['posts'] ) ) {
1826 1693 $this->processed_posts = $this->args['posts'];
1827 1694 }
1828 1695
@@ -1840,9 +1707,6 @@
1840 1707
1841 1708 if ( ! empty( $this->args['terms_meta'] ) ) {
1842 1709 $this->terms_meta = $this->args['terms_meta'];
1843 1710 }
1844 -
1845 - // Register with Jetpack Sync for better analytics tracking.
1846 - add_filter( 'jetpack_sync_known_importers', [ $this, 'register_jetpack_importer' ] );
1847 1711 }
1848 1712 }