PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.1.9
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.1.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 +165 -61 3.0.43.1.9 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,39 @@
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 + 'posts',
651 + 'output',
652 + 'menu_item_orphans',
653 + 'processed_menu_items',
654 + 'post_orphans',
655 + 'processed_posts',
656 + 'featured_images',
657 + ];
658 + $this->retrieve_attributes($attributes);
659 +
585 660 $this->posts = apply_filters( 'wp_import_posts', $this->posts );
586 661
587 - foreach ( $this->posts as $post ) {
662 + $processed_templates = $this->origin->get_progress([], $this->import_data_key);
663 +
664 + foreach ( $this->posts as $key => $post ) {
665 + if (in_array($key, $processed_templates)) {
666 + continue;
667 + }
668 +
669 + // Add the template to the processed templates and update the session data
670 + $processed[] = $key;
671 + $this->origin->update_progress( $processed, null, $this->import_data_key);
672 +
588 673 $post = apply_filters( 'wp_import_post_data_raw', $post );
589 674
590 675 if ( ! post_type_exists( $post['post_type'] ) ) {
591 676 /* translators: 1: Post title, 2: Post type. */
@@ -601,8 +686,12 @@
601 686 if ( 'auto-draft' === $post['status'] ) {
602 687 continue;
603 688 }
604 689
690 + if(!empty($post['post_content']) && !empty($post['post_id'])){
691 + $post['post_content'] = Utils::import_and_replace_attachments($post['post_content'], $post['post_id']);
692 + }
693 +
605 694 if ( 'nav_menu_item' === $post['post_type'] ) {
606 695 $result['succeed'] += $this->process_menu_item( $post );
607 696 continue;
608 697 }
@@ -696,8 +785,21 @@
696 785 $result['failed'][] = $original_post_id;
697 786
698 787 $this->output['errors'][] = $error;
699 788
789 + // Add the template to the processed templates and update the session data
790 + $this->backup_attributes($attributes);
791 + $this->origin->update_progress( null, [ $backup_key => $result ], $this->import_data_key);
792 +
793 + // If it's not the last item, send the SSE message and exit
794 + if( end($this->posts) !== $post) {
795 + $this->origin->sse_message( [
796 + 'type' => 'continue',
797 + 'action' => 'continue',
798 + 'results' => __METHOD__ . '::' . __LINE__,
799 + ] );
800 + exit;
801 + }
700 802 continue;
701 803 }
702 804
703 805 $result['succeed'][ $original_post_id ] = $post_id;
@@ -852,8 +954,22 @@
852 954 }
853 955 }
854 956
855 957 do_action( 'templately_import.process_post', $post, $result, $this );
958 +
959 + // Add the template to the processed templates and update the session data
960 + $this->backup_attributes($attributes);
961 + $this->origin->update_progress( null, [ $backup_key => $result ], $this->import_data_key);
962 +
963 + // If it's not the last item, send the SSE message and exit
964 + if( end($this->posts) !== $post) {
965 + $this->origin->sse_message( [
966 + 'type' => 'continue',
967 + 'action' => 'continue',
968 + 'results' => __METHOD__ . '::' . __LINE__,
969 + ] );
970 + exit;
971 + }
856 972 }
857 973
858 974 unset( $this->posts );
859 975
@@ -1068,9 +1184,19 @@
1068 1184
1069 1185 return $updated_url;
1070 1186 }
1071 1187
1072 - $upload = $this->fetch_remote_file( $url, $post );
1188 + $upload_dir = wp_upload_dir( $post['upload_date'] );
1189 + if ( ! ( $upload_dir && false === $upload_dir['error'] ) ) {
1190 + return new WP_Error( 'upload_dir_error', $upload_dir['error'] );
1191 + }
1192 +
1193 + // Move the file to the uploads dir.
1194 + $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1195 + $file_name = wp_unique_filename( $upload_dir['path'], $file_name );
1196 + $dest_file = $upload_dir['path'] . "/$file_name";
1197 + $upload = $this->fetch_remote_file( $url, $dest_file, $upload_dir );
1198 +
1073 1199 if ( is_wp_error( $upload ) ) {
1074 1200 return $upload;
1075 1201 }
1076 1202
@@ -1080,8 +1206,9 @@
1080 1206 } else {
1081 1207 return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'elementor' ) );
1082 1208 }
1083 1209
1210 + $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1084 1211 $post['guid'] = $upload['url'];
1085 1212
1086 1213 // As per wp-admin/includes/upload.php.
1087 1214 $post_id = wp_insert_attachment( $post, $upload['file'] );
@@ -1093,9 +1220,9 @@
1093 1220
1094 1221 // error_log('Metadata: ' . print_r($metadata, true));
1095 1222
1096 1223 // For gutenberg pages
1097 - $metadata = $this->import_sizes($sizes, $metadata, $upload, $post_id);
1224 + $metadata = $this->import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id);
1098 1225
1099 1226 // error_log('Metadata: ' . print_r($metadata, true));
1100 1227 wp_update_attachment_metadata( $post_id, $metadata );
1101 1228
@@ -1118,35 +1245,8 @@
1118 1245
1119 1246 return $parts['dirname'] . '/' . $name;
1120 1247 }
1121 1248
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 1249 /**
1150 1250 * Attempt to download a remote file attachment
1151 1251 *
1152 1252 * @param string $url URL of item to fetch
@@ -1153,16 +1253,12 @@
1153 1253 * @param array $post Attachment details
1154 1254 *
1155 1255 * @return array|WP_Error Local file location details on success, WP_Error otherwise
1156 1256 */
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 ) );
1257 + private function fetch_remote_file( $url, $new_file, $uploads ) {
1258 + // Extract the file name from the new_file.
1259 + $file_name = basename( $new_file );
1160 1260
1161 - if ( ! $file_name ) {
1162 - $file_name = md5( $url );
1163 - }
1164 -
1165 1261 // Include the file for the download_url function
1166 1262 if(!function_exists('wp_tempnam')) {
1167 1263 require_once ABSPATH . 'wp-admin/includes/file.php';
1168 1264 }
@@ -1172,17 +1268,24 @@
1172 1268 return new WP_Error( 'import_no_file', esc_html__( 'Could not create temporary file.', 'elementor' ) );
1173 1269 }
1174 1270
1175 1271 // 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 - ] );
1272 + $attempt = 0;
1273 + $retry_count = 3;
1274 + $remote_response = null;
1275 + do {
1276 + $remote_response = wp_safe_remote_get( $url, [
1277 + 'timeout' => 300,
1278 + 'stream' => true,
1279 + 'filename' => $tmp_file_name,
1280 + 'headers' => [
1281 + 'Accept-Encoding' => 'identity',
1282 + ]
1283 + ] );
1284 + $attempt++;
1285 + } while (is_wp_error( $remote_response ) && $attempt < $retry_count);
1184 1286
1287 +
1185 1288 if ( is_wp_error( $remote_response ) ) {
1186 1289 @unlink( $tmp_file_name );
1187 1290
1188 1291 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 +1295,8 @@
1192 1295
1193 1296 // Make sure the fetch was successful.
1194 1297 if ( 200 !== $remote_response_code ) {
1195 1298 @unlink( $tmp_file_name );
1196 - Helper::log($url);
1197 - Helper::log($remote_response);
1198 1299 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 1300 }
1200 1301
1201 1302 $headers = wp_remote_retrieve_headers( $remote_response );
@@ -1261,16 +1362,8 @@
1261 1362 if ( ( ! $type || ! $ext ) && ! current_user_can( 'unfiltered_upload' ) ) {
1262 1363 return new WP_Error( 'import_file_error', esc_html__( 'Sorry, this file type is not permitted for security reasons.', 'elementor' ) );
1263 1364 }
1264 1365
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 1366 $move_new_file = copy( $tmp_file_name, $new_file );
1274 1367
1275 1368 if ( ! $move_new_file ) {
1276 1369 @unlink( $tmp_file_name );
@@ -1291,9 +1384,8 @@
1291 1384 ];
1292 1385
1293 1386 // Keep track of the old and new urls so we can substitute them later.
1294 1387 $this->url_remap[ $url ] = $upload['url'];
1295 - $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1296 1388 // Keep track of the destination if the remote url is redirected somewhere else.
1297 1389 if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
1298 1390 $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1299 1391 }
@@ -1378,9 +1470,9 @@
1378 1470 'resized' => false,
1379 1471 );
1380 1472 }
1381 1473
1382 - public function import_sizes($sizes, $metadata, $upload, $post_id) {
1474 + public function import_sizes($sizes, $metadata, $upload, $upload_dir, $post_id) {
1383 1475 if (!empty($sizes)) {
1384 1476 do_action( 'templately_import.finalize_gutenberg_attachment', $post_id );
1385 1477
1386 1478 $size_dimensions = $this->extract_sizes($sizes);
@@ -1388,9 +1480,9 @@
1388 1480
1389 1481 foreach ($size_dimensions as $size_dimension => $__url) {
1390 1482 if (!$this->size_exists_in_metadata($size_dimension, $metadata)) {
1391 1483 $unique_destination_file = $this->create_unique_destination_file($upload['file'], $size_dimension);
1392 - $missing_size = $this->import_size($__url, $unique_destination_file);
1484 + $missing_size = $this->fetch_remote_file($__url, $unique_destination_file, $upload_dir);
1393 1485
1394 1486 if($missing_size && !is_wp_error($missing_size)) {
1395 1487 $metadata['sizes'][$size_dimension] = $this->create_size_array($unique_destination_file, $size_dimension);
1396 1488 do_action( 'templately_import.finalize_gutenberg_attachment', $post_id, $size_dimension );
@@ -1588,10 +1680,22 @@
1588 1680 */
1589 1681 public function __construct( $file, array $args = [] ) {
1590 1682 parent::__construct();
1591 1683
1592 - $this->requested_file_path = $file;
1593 1684 $this->args = $args;
1685 +
1686 + if ( ! empty( $args['json'] ) ) {
1687 + $this->json = $args['json'];
1688 + }
1689 +
1690 + if ( ! empty( $args['origin'] ) ) {
1691 + $this->origin = $args['origin'];
1692 + }
1693 +
1694 + if ( ! empty( $file ) ) {
1695 + $this->requested_file_path = $file;
1696 + $this->import_data_key = 'wp_importer_attributes_' . md5($this->requested_file_path);
1697 + }
1594 1698
1595 1699 if ( ! empty( $this->args['fetch_attachments'] ) ) {
1596 1700 $this->fetch_attachments = true;
1597 1701 }