PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.2.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.2.0
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 +164 -61 3.0.43.2.0 View file →
@@ -55,8 +55,12 @@
55 55 /**
56 56 * @var string
57 57 */
58 58 private $requested_file_path;
59 + /**
60 + * @var string
61 + */
62 + private $import_data_key;
59 63
60 64 /**
61 65 * @var array
62 66 */
@@ -62,8 +66,13 @@
62 66 */
63 67 private $args;
64 68
65 69 /**
70 + * @var FullSiteImport
71 + */
72 + private $origin;
73 +
74 + /**
66 75 * @var array
67 76 */
68 77 private $output = [
69 78 'status' => 'failed',
@@ -343,8 +352,30 @@
343 352 }
344 353 }
345 354 }
346 355
356 + private function retrieve_attributes($attributes){
357 + $params = $this->origin->get_request_params();
358 + $attr_values = $params["imported_data"][$this->import_data_key] ?? [];
359 + foreach ($attributes as $attribute) {
360 + if(isset($attr_values[$attribute])){
361 + $this->$attribute = $attr_values[$attribute];
362 + }
363 + }
364 + }
365 +
366 + private function backup_attributes($attributes){
367 + $params = $this->origin->get_request_params();
368 + $attr_values = $params["imported_data"][$this->import_data_key] ?? [];
369 +
370 + foreach ($attributes as $attribute) {
371 + if(isset($this->$attribute)){
372 + $attr_values[$attribute] = $this->$attribute;
373 + }
374 + }
375 + $this->origin->update_progress( null, [$this->import_data_key => $attr_values]);
376 + }
377 +
347 378 /**
348 379 * Map old author logins to local user IDs based on decisions made
349 380 * in import options form. Can map to an existing user, create a new user
350 381 * or falls back to the current user in case of error with either of the previous
@@ -353,8 +384,20 @@
353 384 if ( ! isset( $this->args['imported_authors'] ) ) {
354 385 return;
355 386 }
356 387
388 + $attributes = [
389 + 'processed_authors',
390 + 'author_mapping',
391 + 'output',
392 + ];
393 +
394 + $processed_templates = $this->origin->get_progress([], $this->import_data_key);
395 + if (!empty($processed_templates)) {
396 + $this->retrieve_attributes($attributes);
397 + return;
398 + }
399 +
357 400 $create_users = apply_filters( 'import_allow_create_users', self::DEFAULT_ALLOW_CREATE_USERS );
358 401
359 402 foreach ( (array) $this->args['imported_authors'] as $i => $old_login ) {
360 403 // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
@@ -409,8 +452,11 @@
409 452 }
410 453 $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
411 454 }
412 455 }
456 +
457 + $this->backup_attributes($attributes);
458 + $this->origin->update_progress( true, null, $this->import_data_key );
413 459 }
414 460
415 461 /**
416 462 * Create new terms based on import information
@@ -419,13 +465,26 @@
419 465 *
420 466 * @return array|array[] the ids of succeed/failed imported terms.
421 467 */
422 468 private function process_terms(): array {
423 - $result = [
469 + $params = $this->origin->get_request_params();
470 + $result = $params["imported_data"]["wp_import_terms_" . $this->import_data_key] ?? [
424 471 'succeed' => [],
425 472 'failed' => [],
426 473 ];
427 474
475 + $attributes = [
476 + 'terms',
477 + 'output',
478 + 'mapped_terms_slug',
479 + 'processed_terms',
480 + ];
481 + $processed_templates = $this->origin->get_progress([], $this->import_data_key);
482 + if (!empty($processed_templates)) {
483 + $this->retrieve_attributes($attributes);
484 + return $result;
485 + }
486 +
428 487 $this->terms = apply_filters( 'wp_import_terms', $this->terms );
429 488 if ( empty( $this->terms ) ) {
430 489 return $result;
431 490 }
@@ -505,8 +564,11 @@
505 564 }
506 565
507 566 unset( $this->terms );
508 567
568 + $this->backup_attributes($attributes);
569 + // Add the template to the processed templates and update the session data
570 + $this->origin->update_progress( true, [ "wp_import_terms_" . $this->import_data_key => $result ]);
509 571 return $result;
510 572 }
511 573
512 574 /**
@@ -576,16 +638,38 @@
576 638 *
577 639 * @return array the ids of succeed/failed imported posts.
578 640 */
579 641 private function process_posts(): array {
580 - $result = [
642 + $backup_key = "wp_import_" . $this->import_data_key;
643 + $params = $this->origin->get_request_params();
644 + $result = $params["imported_data"][$backup_key] ?? [
581 645 'succeed' => [],
582 646 'failed' => [],
583 647 ];
584 648
649 + $attributes = [
650 + 'output',
651 + 'menu_item_orphans',
652 + 'processed_menu_items',
653 + 'post_orphans',
654 + 'processed_posts',
655 + 'featured_images',
656 + ];
657 + $this->retrieve_attributes($attributes);
658 +
585 659 $this->posts = apply_filters( 'wp_import_posts', $this->posts );
586 660
587 - foreach ( $this->posts as $post ) {
661 + $processed_templates = $this->origin->get_progress([], $this->import_data_key);
662 +
663 + foreach ( $this->posts as $key => $post ) {
664 + if (in_array($key, $processed_templates)) {
665 + continue;
666 + }
667 +
668 + // Add the template to the processed templates and update the session data
669 + $processed_templates[] = $key;
670 + $this->origin->update_progress( $processed_templates, null, $this->import_data_key);
671 +
588 672 $post = apply_filters( 'wp_import_post_data_raw', $post );
589 673
590 674 if ( ! post_type_exists( $post['post_type'] ) ) {
591 675 /* translators: 1: Post title, 2: Post type. */
@@ -601,8 +685,12 @@
601 685 if ( 'auto-draft' === $post['status'] ) {
602 686 continue;
603 687 }
604 688
689 + if(!empty($post['post_content']) && !empty($post['post_id'])){
690 + $post['post_content'] = Utils::import_and_replace_attachments($post['post_content'], $post['post_id']);
691 + }
692 +
605 693 if ( 'nav_menu_item' === $post['post_type'] ) {
606 694 $result['succeed'] += $this->process_menu_item( $post );
607 695 continue;
608 696 }
@@ -696,8 +784,21 @@
696 784 $result['failed'][] = $original_post_id;
697 785
698 786 $this->output['errors'][] = $error;
699 787
788 + // Add the template to the processed templates and update the session data
789 + $this->backup_attributes($attributes);
790 + $this->origin->update_progress( null, [ $backup_key => $result ], $this->import_data_key);
791 +
792 + // If it's not the last item, send the SSE message and exit
793 + if( end($this->posts) !== $post) {
794 + $this->origin->sse_message( [
795 + 'type' => 'continue',
796 + 'action' => 'continue',
797 + 'results' => __METHOD__ . '::' . __LINE__,
798 + ] );
799 + exit;
800 + }
700 801 continue;
701 802 }
702 803
703 804 $result['succeed'][ $original_post_id ] = $post_id;
@@ -852,8 +953,22 @@
852 953 }
853 954 }
854 955
855 956 do_action( 'templately_import.process_post', $post, $result, $this );
957 +
958 + // Add the template to the processed templates and update the session data
959 + $this->backup_attributes($attributes);
960 + $this->origin->update_progress( null, [ $backup_key => $result ], $this->import_data_key);
961 +
962 + // If it's not the last item, send the SSE message and exit
963 + if( end($this->posts) !== $post) {
964 + $this->origin->sse_message( [
965 + 'type' => 'continue',
966 + 'action' => 'continue',
967 + 'results' => __METHOD__ . '::' . __LINE__,
968 + ] );
969 + exit;
970 + }
856 971 }
857 972
858 973 unset( $this->posts );
859 974
@@ -1068,9 +1183,19 @@
1068 1183
1069 1184 return $updated_url;
1070 1185 }
1071 1186
1072 - $upload = $this->fetch_remote_file( $url, $post );
1187 + $upload_dir = wp_upload_dir( $post['upload_date'] );
1188 + if ( ! ( $upload_dir && false === $upload_dir['error'] ) ) {
1189 + return new WP_Error( 'upload_dir_error', $upload_dir['error'] );
1190 + }
1191 +
1192 + // Move the file to the uploads dir.
1193 + $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1194 + $file_name = wp_unique_filename( $upload_dir['path'], $file_name );
1195 + $dest_file = $upload_dir['path'] . "/$file_name";
1196 + $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1197 +
1073 1198 if ( is_wp_error( $upload ) ) {
1074 1199 return $upload;
1075 1200 }
1076 1201
@@ -1080,8 +1205,9 @@
1080 1205 } else {
1081 1206 return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'elementor' ) );
1082 1207 }
1083 1208
1209 + $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1084 1210 $post['guid'] = $upload['url'];
1085 1211
1086 1212 // As per wp-admin/includes/upload.php.
1087 1213 $post_id = wp_insert_attachment( $post, $upload['file'] );
@@ -1093,9 +1219,9 @@
1093 1219
1094 1220 // error_log('Metadata: ' . print_r($metadata, true));
1095 1221
1096 1222 // For gutenberg pages
1097 - $metadata = $this->import_sizes($sizes, $metadata, $upload, $post_id);
1223 + $metadata = $this->import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id);
1098 1224
1099 1225 // error_log('Metadata: ' . print_r($metadata, true));
1100 1226 wp_update_attachment_metadata( $post_id, $metadata );
1101 1227
@@ -1118,35 +1244,8 @@
1118 1244
1119 1245 return $parts['dirname'] . '/' . $name;
1120 1246 }
1121 1247
1122 - private function import_size($remote_url, $destination_path) {
1123 - // Include the file for the download_url function
1124 - if(!function_exists('download_url')) {
1125 - require_once ABSPATH . 'wp-admin/includes/file.php';
1126 - }
1127 -
1128 - // Download file to temp dir
1129 - $temp_file = download_url($remote_url);
1130 -
1131 - // Check for download errors
1132 - if(is_wp_error($temp_file)) {
1133 - return $temp_file;
1134 - }
1135 -
1136 - // Move temp file to destination path
1137 - $result = copy($temp_file, $destination_path);
1138 -
1139 - // Remove temp file
1140 - @unlink($temp_file);
1141 -
1142 - if (!$result) {
1143 - return false;
1144 - }
1145 -
1146 - return true;
1147 - }
1148 -
1149 1248 /**
1150 1249 * Attempt to download a remote file attachment
1151 1250 *
1152 1251 * @param string $url URL of item to fetch
@@ -1153,16 +1252,12 @@
1153 1252 * @param array $post Attachment details
1154 1253 *
1155 1254 * @return array|WP_Error Local file location details on success, WP_Error otherwise
1156 1255 */
1157 - private function fetch_remote_file( $url, $post ) {
1158 - // Extract the file name from the URL.
1159 - $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1256 + private function fetch_remote_file( $url, $new_file, $uploads ) {
1257 + // Extract the file name from the new_file.
1258 + $file_name = basename( $new_file );
1160 1259
1161 - if ( ! $file_name ) {
1162 - $file_name = md5( $url );
1163 - }
1164 -
1165 1260 // Include the file for the download_url function
1166 1261 if(!function_exists('wp_tempnam')) {
1167 1262 require_once ABSPATH . 'wp-admin/includes/file.php';
1168 1263 }
@@ -1172,17 +1267,24 @@
1172 1267 return new WP_Error( 'import_no_file', esc_html__( 'Could not create temporary file.', 'elementor' ) );
1173 1268 }
1174 1269
1175 1270 // Fetch the remote URL and write it to the placeholder file.
1176 - $remote_response = wp_safe_remote_get( $url, [
1177 - 'timeout' => 300,
1178 - 'stream' => true,
1179 - 'filename' => $tmp_file_name,
1180 - 'headers' => [
1181 - 'Accept-Encoding' => 'identity',
1182 - ]
1183 - ] );
1271 + $attempt = 0;
1272 + $retry_count = 3;
1273 + $remote_response = null;
1274 + do {
1275 + $remote_response = wp_safe_remote_get( $url, [
1276 + 'timeout' => 300,
1277 + 'stream' => true,
1278 + 'filename' => $tmp_file_name,
1279 + 'headers' => [
1280 + 'Accept-Encoding' => 'identity',
1281 + ]
1282 + ] );
1283 + $attempt++;
1284 + } while (is_wp_error( $remote_response ) && $attempt < $retry_count);
1184 1285
1286 +
1185 1287 if ( is_wp_error( $remote_response ) ) {
1186 1288 @unlink( $tmp_file_name );
1187 1289
1188 1290 return new WP_Error( 'import_file_error', sprintf( /* translators: 1: WordPress error message, 2: WordPress error code. */ esc_html__( 'Request failed due to an error: %1$s (%2$s)', 'elementor' ), esc_html( $remote_response->get_error_message() ), esc_html( $remote_response->get_error_code() ) ) );
@@ -1192,10 +1294,8 @@
1192 1294
1193 1295 // Make sure the fetch was successful.
1194 1296 if ( 200 !== $remote_response_code ) {
1195 1297 @unlink( $tmp_file_name );
1196 - Helper::log($url);
1197 - Helper::log($remote_response);
1198 1298 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 ) ) );
1199 1299 }
1200 1300
1201 1301 $headers = wp_remote_retrieve_headers( $remote_response );
@@ -1261,16 +1361,8 @@
1261 1361 if ( ( ! $type || ! $ext ) && ! current_user_can( 'unfiltered_upload' ) ) {
1262 1362 return new WP_Error( 'import_file_error', esc_html__( 'Sorry, this file type is not permitted for security reasons.', 'elementor' ) );
1263 1363 }
1264 1364
1265 - $uploads = wp_upload_dir( $post['upload_date'] );
1266 - if ( ! ( $uploads && false === $uploads['error'] ) ) {
1267 - return new WP_Error( 'upload_dir_error', $uploads['error'] );
1268 - }
1269 -
1270 - // Move the file to the uploads dir.
1271 - $file_name = wp_unique_filename( $uploads['path'], $file_name );
1272 - $new_file = $uploads['path'] . "/$file_name";
1273 1365 $move_new_file = copy( $tmp_file_name, $new_file );
1274 1366
1275 1367 if ( ! $move_new_file ) {
1276 1368 @unlink( $tmp_file_name );
@@ -1291,9 +1383,8 @@
1291 1383 ];
1292 1384
1293 1385 // Keep track of the old and new urls so we can substitute them later.
1294 1386 $this->url_remap[ $url ] = $upload['url'];
1295 - $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1296 1387 // Keep track of the destination if the remote url is redirected somewhere else.
1297 1388 if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
1298 1389 $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1299 1390 }
@@ -1378,9 +1469,9 @@
1378 1469 'resized' => false,
1379 1470 );
1380 1471 }
1381 1472
1382 - public function import_sizes($sizes, $metadata, $upload, $post_id) {
1473 + public function import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id) {
1383 1474 if (!empty($sizes)) {
1384 1475 do_action( 'templately_import.finalize_gutenberg_attachment', $post_id );
1385 1476
1386 1477 $size_dimensions = $this->extract_sizes($sizes);
@@ -1388,9 +1479,9 @@
1388 1479
1389 1480 foreach ($size_dimensions as $size_dimension => $__url) {
1390 1481 if (!$this->size_exists_in_metadata($size_dimension, $metadata)) {
1391 1482 $unique_destination_file = $this->create_unique_destination_file($upload['file'], $size_dimension);
1392 - $missing_size = $this->import_size($__url, $unique_destination_file);
1483 + $missing_size = $this->fetch_remote_file($__url, $unique_destination_file, $upload_dir);
1393 1484
1394 1485 if($missing_size && !is_wp_error($missing_size)) {
1395 1486 $metadata['sizes'][$size_dimension] = $this->create_size_array($unique_destination_file, $size_dimension);
1396 1487 do_action( 'templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension );
@@ -1588,10 +1679,22 @@
1588 1679 */
1589 1680 public function __construct( $file, array $args = [] ) {
1590 1681 parent::__construct();
1591 1682
1592 - $this->requested_file_path = $file;
1593 1683 $this->args = $args;
1684 +
1685 + if ( ! empty( $args['json'] ) ) {
1686 + $this->json = $args['json'];
1687 + }
1688 +
1689 + if ( ! empty( $args['origin'] ) ) {
1690 + $this->origin = $args['origin'];
1691 + }
1692 +
1693 + if ( ! empty( $file ) ) {
1694 + $this->requested_file_path = $file;
1695 + $this->import_data_key = 'wp_importer_attributes_' . md5($this->requested_file_path);
1696 + }
1594 1697
1595 1698 if ( ! empty( $this->args['fetch_attachments'] ) ) {
1596 1699 $this->fetch_attachments = true;
1597 1700 }