WordPress Importer - Version 0.8

Version Description

  • Update minimum WordPress requirement to 5.2.
  • Update minimum PHP requirement to 5.6.
  • Update compatibility tested-up-to to WordPress 6.1.
  • PHP 8.0, 8.1, and 8.2 compatibility fixes.
  • Fix a bug causing blank lines in content to be ignored when using the Regex Parser.
  • Fix a bug resulting in a PHP fatal error when IMPORT_DEBUG is enabled and a category creation error occurs.
  • Improved Unit testing & automated testing.
Download this release

Release Info

Developer githubsync
Plugin Icon 128x128 WordPress Importer
Version 0.8
Comparing to
See all releases

Code changes from version 0.7 to 0.8

class-wp-import.php CHANGED
@@ -16,26 +16,26 @@ class WP_Import extends WP_Importer {
16
 
17
  // information to import from WXR file
18
  var $version;
19
- var $authors = array();
20
- var $posts = array();
21
- var $terms = array();
22
  var $categories = array();
23
- var $tags = array();
24
- var $base_url = '';
25
 
26
  // mappings from old information to new
27
- var $processed_authors = array();
28
- var $author_mapping = array();
29
- var $processed_terms = array();
30
- var $processed_posts = array();
31
- var $post_orphans = array();
32
  var $processed_menu_items = array();
33
- var $menu_item_orphans = array();
34
- var $missing_menu_items = array();
35
 
36
  var $fetch_attachments = false;
37
- var $url_remap = array();
38
- var $featured_images = array();
39
 
40
  /**
41
  * Registered callback function for the WordPress Importer
@@ -52,15 +52,16 @@ class WP_Import extends WP_Importer {
52
  break;
53
  case 1:
54
  check_admin_referer( 'import-upload' );
55
- if ( $this->handle_upload() )
56
  $this->import_options();
 
57
  break;
58
  case 2:
59
  check_admin_referer( 'import-wordpress' );
60
  $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() );
61
- $this->id = (int) $_POST['import_id'];
62
- $file = get_attached_file( $this->id );
63
- set_time_limit(0);
64
  $this->import( $file );
65
  break;
66
  }
@@ -102,7 +103,7 @@ class WP_Import extends WP_Importer {
102
  * @param string $file Path to the WXR file for importing
103
  */
104
  function import_start( $file ) {
105
- if ( ! is_file($file) ) {
106
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
107
  echo __( 'The file does not exist, please try again.', 'wordpress-importer' ) . '</p>';
108
  $this->footer();
@@ -120,11 +121,11 @@ class WP_Import extends WP_Importer {
120
 
121
  $this->version = $import_data['version'];
122
  $this->get_authors_from_import( $import_data );
123
- $this->posts = $import_data['posts'];
124
- $this->terms = $import_data['terms'];
125
  $this->categories = $import_data['categories'];
126
- $this->tags = $import_data['tags'];
127
- $this->base_url = esc_url( $import_data['base_url'] );
128
 
129
  wp_defer_term_counting( true );
130
  wp_defer_comment_counting( true );
@@ -166,14 +167,14 @@ class WP_Import extends WP_Importer {
166
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
167
  echo esc_html( $file['error'] ) . '</p>';
168
  return false;
169
- } else if ( ! file_exists( $file['file'] ) ) {
170
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
171
  printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'wordpress-importer' ), esc_html( $file['file'] ) );
172
  echo '</p>';
173
  return false;
174
  }
175
 
176
- $this->id = (int) $file['id'];
177
  $import_data = $this->parse( $file['file'] );
178
  if ( is_wp_error( $import_data ) ) {
179
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
@@ -184,7 +185,7 @@ class WP_Import extends WP_Importer {
184
  $this->version = $import_data['version'];
185
  if ( $this->version > $this->max_wxr_version ) {
186
  echo '<div class="error"><p><strong>';
187
- printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'wordpress-importer' ), esc_html($import_data['version']) );
188
  echo '</strong></p></div>';
189
  }
190
 
@@ -204,7 +205,7 @@ class WP_Import extends WP_Importer {
204
  function get_authors_from_import( $import_data ) {
205
  if ( ! empty( $import_data['authors'] ) ) {
206
  $this->authors = $import_data['authors'];
207
- // no author information, grab it from the posts
208
  } else {
209
  foreach ( $import_data['posts'] as $post ) {
210
  $login = sanitize_user( $post['post_author'], true );
@@ -214,11 +215,12 @@ class WP_Import extends WP_Importer {
214
  continue;
215
  }
216
 
217
- if ( ! isset($this->authors[$login]) )
218
- $this->authors[$login] = array(
219
- 'author_login' => $login,
220
- 'author_display_name' => $post['post_author']
221
  );
 
222
  }
223
  }
224
  }
@@ -229,7 +231,8 @@ class WP_Import extends WP_Importer {
229
  */
230
  function import_options() {
231
  $j = 0;
232
- ?>
 
233
  <form action="<?php echo admin_url( 'admin.php?import=wordpress&amp;step=2' ); ?>" method="post">
234
  <?php wp_nonce_field( 'import-wordpress' ); ?>
235
  <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
@@ -238,7 +241,7 @@ class WP_Import extends WP_Importer {
238
  <h3><?php _e( 'Assign Authors', 'wordpress-importer' ); ?></h3>
239
  <p><?php _e( 'To make it simpler for you to edit and save the imported content, you may want to reassign the author of the imported item to an existing user of this site, such as your primary administrator account.', 'wordpress-importer' ); ?></p>
240
  <?php if ( $this->allow_create_users() ) : ?>
241
- <p><?php printf( __( 'If a new user is created by WordPress, a new password will be randomly generated and the new user&#8217;s role will be set as %s. Manually changing the new user&#8217;s details will be necessary.', 'wordpress-importer' ), esc_html( get_option('default_role') ) ); ?></p>
242
  <?php endif; ?>
243
  <ol id="authors">
244
  <?php foreach ( $this->authors as $author ) : ?>
@@ -257,7 +260,8 @@ class WP_Import extends WP_Importer {
257
 
258
  <p class="submit"><input type="submit" class="button" value="<?php esc_attr_e( 'Submit', 'wordpress-importer' ); ?>" /></p>
259
  </form>
260
- <?php
 
261
  }
262
 
263
  /**
@@ -270,16 +274,19 @@ class WP_Import extends WP_Importer {
270
  function author_select( $n, $author ) {
271
  _e( 'Import author:', 'wordpress-importer' );
272
  echo ' <strong>' . esc_html( $author['author_display_name'] );
273
- if ( $this->version != '1.0' ) echo ' (' . esc_html( $author['author_login'] ) . ')';
 
 
274
  echo '</strong><br />';
275
 
276
- if ( $this->version != '1.0' )
277
  echo '<div style="margin-left:18px">';
 
278
 
279
  $create_users = $this->allow_create_users();
280
  if ( $create_users ) {
281
- echo '<label for="user_new_'. $n . '">';
282
- if ( $this->version != '1.0' ) {
283
  _e( 'or create new user with login name:', 'wordpress-importer' );
284
  $value = '';
285
  } else {
@@ -288,30 +295,33 @@ class WP_Import extends WP_Importer {
288
  }
289
  echo '</label>';
290
 
291
- echo ' <input type="text" id="user_new_' . $n . '" name="user_new['.$n.']" value="'. $value .'" /><br />';
292
  }
293
 
294
- echo '<label for="imported_authors_'. $n . '">';
295
- if ( ! $create_users && $this->version == '1.0' ) {
296
  _e( 'assign posts to an existing user:', 'wordpress-importer' );
297
  } else {
298
  _e( 'or assign posts to an existing user:', 'wordpress-importer' );
299
  }
300
  echo '</label>';
301
 
302
- echo ' ' . wp_dropdown_users( array(
303
- 'name' => "user_map[$n]",
304
- 'id' => 'imported_authors_' . $n,
305
- 'multi' => true,
306
- 'show_option_all' => __( '- Select -', 'wordpress-importer' ),
307
- 'show' => 'display_name_with_login',
308
- 'echo' => 0,
309
- ) );
 
 
310
 
311
- echo '<input type="hidden" name="imported_authors['.$n.']" value="' . esc_attr( $author['author_login'] ) . '" />';
312
 
313
- if ( $this->version != '1.0' )
314
  echo '</div>';
 
315
  }
316
 
317
  /**
@@ -320,55 +330,60 @@ class WP_Import extends WP_Importer {
320
  * or falls back to the current user in case of error with either of the previous
321
  */
322
  function get_author_mapping() {
323
- if ( ! isset( $_POST['imported_authors'] ) )
324
  return;
 
325
 
326
  $create_users = $this->allow_create_users();
327
 
328
  foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
329
  // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
330
  $santized_old_login = sanitize_user( $old_login, true );
331
- $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false;
332
 
333
- if ( ! empty( $_POST['user_map'][$i] ) ) {
334
- $user = get_userdata( intval($_POST['user_map'][$i]) );
335
  if ( isset( $user->ID ) ) {
336
- if ( $old_id )
337
- $this->processed_authors[$old_id] = $user->ID;
338
- $this->author_mapping[$santized_old_login] = $user->ID;
 
339
  }
340
- } else if ( $create_users ) {
341
- if ( ! empty($_POST['user_new'][$i]) ) {
342
- $user_id = wp_create_user( $_POST['user_new'][$i], wp_generate_password() );
343
- } else if ( $this->version != '1.0' ) {
344
  $user_data = array(
345
- 'user_login' => $old_login,
346
- 'user_pass' => wp_generate_password(),
347
- 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '',
348
- 'display_name' => $this->authors[$old_login]['author_display_name'],
349
- 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '',
350
- 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '',
351
  );
352
- $user_id = wp_insert_user( $user_data );
353
  }
354
 
355
  if ( ! is_wp_error( $user_id ) ) {
356
- if ( $old_id )
357
- $this->processed_authors[$old_id] = $user_id;
358
- $this->author_mapping[$santized_old_login] = $user_id;
 
359
  } else {
360
- printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html($this->authors[$old_login]['author_display_name']) );
361
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
362
  echo ' ' . $user_id->get_error_message();
 
363
  echo '<br />';
364
  }
365
  }
366
 
367
  // failsafe: if the user_id was invalid, default to the current user
368
- if ( ! isset( $this->author_mapping[$santized_old_login] ) ) {
369
- if ( $old_id )
370
- $this->processed_authors[$old_id] = (int) get_current_user_id();
371
- $this->author_mapping[$santized_old_login] = (int) get_current_user_id();
 
372
  }
373
  }
374
  }
@@ -381,16 +396,20 @@ class WP_Import extends WP_Importer {
381
  function process_categories() {
382
  $this->categories = apply_filters( 'wp_import_categories', $this->categories );
383
 
384
- if ( empty( $this->categories ) )
385
  return;
 
386
 
387
  foreach ( $this->categories as $cat ) {
388
  // if the category already exists leave it alone
389
  $term_id = term_exists( $cat['category_nicename'], 'category' );
390
  if ( $term_id ) {
391
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
392
- if ( isset($cat['term_id']) )
393
- $this->processed_terms[intval($cat['term_id'])] = (int) $term_id;
 
 
 
394
  continue;
395
  }
396
 
@@ -404,14 +423,16 @@ class WP_Import extends WP_Importer {
404
  'category_description' => wp_slash( $description ),
405
  );
406
 
407
- $id = wp_insert_category( $data );
408
  if ( ! is_wp_error( $id ) && $id > 0 ) {
409
- if ( isset($cat['term_id']) )
410
- $this->processed_terms[intval($cat['term_id'])] = $id;
 
411
  } else {
412
- printf( __( 'Failed to import category %s', 'wordpress-importer' ), esc_html($cat['category_nicename']) );
413
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
414
  echo ': ' . $id->get_error_message();
 
415
  echo '<br />';
416
  continue;
417
  }
@@ -430,16 +451,20 @@ class WP_Import extends WP_Importer {
430
  function process_tags() {
431
  $this->tags = apply_filters( 'wp_import_tags', $this->tags );
432
 
433
- if ( empty( $this->tags ) )
434
  return;
 
435
 
436
  foreach ( $this->tags as $tag ) {
437
  // if the tag already exists leave it alone
438
  $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
439
  if ( $term_id ) {
440
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
441
- if ( isset($tag['term_id']) )
442
- $this->processed_terms[intval($tag['term_id'])] = (int) $term_id;
 
 
 
443
  continue;
444
  }
445
 
@@ -451,12 +476,14 @@ class WP_Import extends WP_Importer {
451
 
452
  $id = wp_insert_term( wp_slash( $tag['tag_name'] ), 'post_tag', $args );
453
  if ( ! is_wp_error( $id ) ) {
454
- if ( isset($tag['term_id']) )
455
- $this->processed_terms[intval($tag['term_id'])] = $id['term_id'];
 
456
  } else {
457
- printf( __( 'Failed to import post tag %s', 'wordpress-importer' ), esc_html($tag['tag_name']) );
458
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
459
  echo ': ' . $id->get_error_message();
 
460
  echo '<br />';
461
  continue;
462
  }
@@ -475,16 +502,20 @@ class WP_Import extends WP_Importer {
475
  function process_terms() {
476
  $this->terms = apply_filters( 'wp_import_terms', $this->terms );
477
 
478
- if ( empty( $this->terms ) )
479
  return;
 
480
 
481
  foreach ( $this->terms as $term ) {
482
  // if the term already exists in the correct taxonomy leave it alone
483
  $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
484
  if ( $term_id ) {
485
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
486
- if ( isset($term['term_id']) )
487
- $this->processed_terms[intval($term['term_id'])] = (int) $term_id;
 
 
 
488
  continue;
489
  }
490
 
@@ -501,17 +532,19 @@ class WP_Import extends WP_Importer {
501
  $args = array(
502
  'slug' => $term['slug'],
503
  'description' => wp_slash( $description ),
504
- 'parent' => (int) $parent
505
  );
506
 
507
  $id = wp_insert_term( wp_slash( $term['term_name'] ), $term['term_taxonomy'], $args );
508
  if ( ! is_wp_error( $id ) ) {
509
- if ( isset($term['term_id']) )
510
- $this->processed_terms[intval($term['term_id'])] = $id['term_id'];
 
511
  } else {
512
- printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($term['term_taxonomy']), esc_html($term['term_name']) );
513
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
514
  echo ': ' . $id->get_error_message();
 
515
  echo '<br />';
516
  continue;
517
  }
@@ -531,10 +564,6 @@ class WP_Import extends WP_Importer {
531
  * @param int $term_id ID of the newly created term.
532
  */
533
  protected function process_termmeta( $term, $term_id ) {
534
- if ( ! function_exists( 'add_term_meta' ) ) {
535
- return;
536
- }
537
-
538
  if ( ! isset( $term['termmeta'] ) ) {
539
  $term['termmeta'] = array();
540
  }
@@ -602,18 +631,23 @@ class WP_Import extends WP_Importer {
602
  $post = apply_filters( 'wp_import_post_data_raw', $post );
603
 
604
  if ( ! post_type_exists( $post['post_type'] ) ) {
605
- printf( __( 'Failed to import &#8220;%s&#8221;: Invalid post type %s', 'wordpress-importer' ),
606
- esc_html($post['post_title']), esc_html($post['post_type']) );
 
 
 
607
  echo '<br />';
608
  do_action( 'wp_import_post_exists', $post );
609
  continue;
610
  }
611
 
612
- if ( isset( $this->processed_posts[$post['post_id']] ) && ! empty( $post['post_id'] ) )
613
  continue;
 
614
 
615
- if ( $post['status'] == 'auto-draft' )
616
  continue;
 
617
 
618
  if ( 'nav_menu_item' == $post['post_type'] ) {
619
  $this->process_menu_item( $post );
@@ -639,85 +673,105 @@ class WP_Import extends WP_Importer {
639
  $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
640
 
641
  if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
642
- printf( __('%s &#8220;%s&#8221; already exists.', 'wordpress-importer'), $post_type_object->labels->singular_name, esc_html($post['post_title']) );
643
  echo '<br />';
644
- $comment_post_ID = $post_id = $post_exists;
 
645
  $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
646
  } else {
647
  $post_parent = (int) $post['post_parent'];
648
  if ( $post_parent ) {
649
  // if we already know the parent, map it to the new local ID
650
- if ( isset( $this->processed_posts[$post_parent] ) ) {
651
- $post_parent = $this->processed_posts[$post_parent];
652
- // otherwise record the parent for later
653
  } else {
654
- $this->post_orphans[intval($post['post_id'])] = $post_parent;
655
- $post_parent = 0;
656
  }
657
  }
658
 
659
  // map the post author
660
  $author = sanitize_user( $post['post_author'], true );
661
- if ( isset( $this->author_mapping[$author] ) )
662
- $author = $this->author_mapping[$author];
663
- else
664
  $author = (int) get_current_user_id();
 
665
 
666
  $postdata = array(
667
- 'import_id' => $post['post_id'], 'post_author' => $author, 'post_date' => $post['post_date'],
668
- 'post_date_gmt' => $post['post_date_gmt'], 'post_content' => $post['post_content'],
669
- 'post_excerpt' => $post['post_excerpt'], 'post_title' => $post['post_title'],
670
- 'post_status' => $post['status'], 'post_name' => $post['post_name'],
671
- 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'],
672
- 'guid' => $post['guid'], 'post_parent' => $post_parent, 'menu_order' => $post['menu_order'],
673
- 'post_type' => $post['post_type'], 'post_password' => $post['post_password']
 
 
 
 
 
 
 
 
 
674
  );
675
 
676
- $original_post_ID = $post['post_id'];
677
- $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
678
 
679
  $postdata = wp_slash( $postdata );
680
 
681
  if ( 'attachment' == $postdata['post_type'] ) {
682
- $remote_url = ! empty($post['attachment_url']) ? $post['attachment_url'] : $post['guid'];
683
 
684
  // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
685
  // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
686
  $postdata['upload_date'] = $post['post_date'];
687
  if ( isset( $post['postmeta'] ) ) {
688
- foreach( $post['postmeta'] as $meta ) {
689
- if ( $meta['key'] == '_wp_attached_file' ) {
690
- if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) )
691
  $postdata['upload_date'] = $matches[0];
 
692
  break;
693
  }
694
  }
695
  }
696
 
697
- $comment_post_ID = $post_id = $this->process_attachment( $postdata, $remote_url );
 
698
  } else {
699
- $comment_post_ID = $post_id = wp_insert_post( $postdata, true );
700
- do_action( 'wp_import_insert_post', $post_id, $original_post_ID, $postdata, $post );
 
701
  }
702
 
703
  if ( is_wp_error( $post_id ) ) {
704
- printf( __( 'Failed to import %s &#8220;%s&#8221;', 'wordpress-importer' ),
705
- $post_type_object->labels->singular_name, esc_html($post['post_title']) );
706
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
 
 
 
707
  echo ': ' . $post_id->get_error_message();
 
708
  echo '<br />';
709
  continue;
710
  }
711
 
712
- if ( $post['is_sticky'] == 1 )
713
  stick_post( $post_id );
 
714
  }
715
 
716
  // map pre-import ID to local ID
717
- $this->processed_posts[intval($post['post_id'])] = (int) $post_id;
718
 
719
- if ( ! isset( $post['terms'] ) )
720
  $post['terms'] = array();
 
721
 
722
  $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
723
 
@@ -726,24 +780,25 @@ class WP_Import extends WP_Importer {
726
  $terms_to_set = array();
727
  foreach ( $post['terms'] as $term ) {
728
  // back compat with WXR 1.0 map 'tag' to 'post_tag'
729
- $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
730
  $term_exists = term_exists( $term['slug'], $taxonomy );
731
- $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
732
  if ( ! $term_id ) {
733
  $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
734
  if ( ! is_wp_error( $t ) ) {
735
  $term_id = $t['term_id'];
736
  do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
737
  } else {
738
- printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($taxonomy), esc_html($term['name']) );
739
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
740
  echo ': ' . $t->get_error_message();
 
741
  echo '<br />';
742
  do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
743
  continue;
744
  }
745
  }
746
- $terms_to_set[$taxonomy][] = intval( $term_id );
747
  }
748
 
749
  foreach ( $terms_to_set as $tax => $ids ) {
@@ -753,38 +808,40 @@ class WP_Import extends WP_Importer {
753
  unset( $post['terms'], $terms_to_set );
754
  }
755
 
756
- if ( ! isset( $post['comments'] ) )
757
  $post['comments'] = array();
 
758
 
759
  $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
760
 
761
  // add/update comments
762
  if ( ! empty( $post['comments'] ) ) {
763
- $num_comments = 0;
764
  $inserted_comments = array();
765
  foreach ( $post['comments'] as $comment ) {
766
- $comment_id = $comment['comment_id'];
767
- $newcomments[$comment_id]['comment_post_ID'] = $comment_post_ID;
768
- $newcomments[$comment_id]['comment_author'] = $comment['comment_author'];
769
- $newcomments[$comment_id]['comment_author_email'] = $comment['comment_author_email'];
770
- $newcomments[$comment_id]['comment_author_IP'] = $comment['comment_author_IP'];
771
- $newcomments[$comment_id]['comment_author_url'] = $comment['comment_author_url'];
772
- $newcomments[$comment_id]['comment_date'] = $comment['comment_date'];
773
- $newcomments[$comment_id]['comment_date_gmt'] = $comment['comment_date_gmt'];
774
- $newcomments[$comment_id]['comment_content'] = $comment['comment_content'];
775
- $newcomments[$comment_id]['comment_approved'] = $comment['comment_approved'];
776
- $newcomments[$comment_id]['comment_type'] = $comment['comment_type'];
777
- $newcomments[$comment_id]['comment_parent'] = $comment['comment_parent'];
778
- $newcomments[$comment_id]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
779
- if ( isset( $this->processed_authors[$comment['comment_user_id']] ) )
780
- $newcomments[$comment_id]['user_id'] = $this->processed_authors[$comment['comment_user_id']];
 
781
  }
782
  ksort( $newcomments );
783
 
784
  foreach ( $newcomments as $key => $comment ) {
785
  // if this is a new post we can skip the comment_exists() check
786
  if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
787
- if ( isset( $inserted_comments[$comment['comment_parent']] ) ) {
788
  $comment['comment_parent'] = $inserted_comments[ $comment['comment_parent'] ];
789
  }
790
 
@@ -794,9 +851,9 @@ class WP_Import extends WP_Importer {
794
 
795
  $inserted_comments[ $key ] = wp_insert_comment( $comment_data );
796
 
797
- do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $comment_post_ID, $post );
798
 
799
- foreach( $comment['commentmeta'] as $meta ) {
800
  $value = maybe_unserialize( $meta['value'] );
801
 
802
  add_comment_meta( $inserted_comments[ $key ], wp_slash( $meta['key'] ), wp_slash_strings_only( $value ) );
@@ -808,22 +865,24 @@ class WP_Import extends WP_Importer {
808
  unset( $newcomments, $inserted_comments, $post['comments'] );
809
  }
810
 
811
- if ( ! isset( $post['postmeta'] ) )
812
  $post['postmeta'] = array();
 
813
 
814
  $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
815
 
816
  // add/update post meta
817
  if ( ! empty( $post['postmeta'] ) ) {
818
  foreach ( $post['postmeta'] as $meta ) {
819
- $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
820
  $value = false;
821
 
822
  if ( '_edit_last' == $key ) {
823
- if ( isset( $this->processed_authors[intval($meta['value'])] ) )
824
- $value = $this->processed_authors[intval($meta['value'])];
825
- else
826
  $key = false;
 
827
  }
828
 
829
  if ( $key ) {
@@ -837,8 +896,9 @@ class WP_Import extends WP_Importer {
837
  do_action( 'import_post_meta', $post_id, $key, $value );
838
 
839
  // if the post has a featured image, take note of this in case of remap
840
- if ( '_thumbnail_id' == $key )
841
- $this->featured_images[$post_id] = (int) $value;
 
842
  }
843
  }
844
  }
@@ -859,11 +919,12 @@ class WP_Import extends WP_Importer {
859
  */
860
  function process_menu_item( $item ) {
861
  // skip draft, orphaned menu items
862
- if ( 'draft' == $item['status'] )
863
  return;
 
864
 
865
  $menu_slug = false;
866
- if ( isset($item['terms']) ) {
867
  // loop through terms, assume first nav_menu term is correct menu
868
  foreach ( $item['terms'] as $term ) {
869
  if ( 'nav_menu' == $term['domain'] ) {
@@ -889,50 +950,53 @@ class WP_Import extends WP_Importer {
889
  $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
890
  }
891
 
892
- foreach ( $item['postmeta'] as $meta )
893
  ${$meta['key']} = $meta['value'];
 
894
 
895
- if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[intval($_menu_item_object_id)] ) ) {
896
- $_menu_item_object_id = $this->processed_terms[intval($_menu_item_object_id)];
897
- } else if ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[intval($_menu_item_object_id)] ) ) {
898
- $_menu_item_object_id = $this->processed_posts[intval($_menu_item_object_id)];
899
- } else if ( 'custom' != $_menu_item_type ) {
900
  // associated object is missing or not imported yet, we'll retry later
901
  $this->missing_menu_items[] = $item;
902
  return;
903
  }
904
 
905
- if ( isset( $this->processed_menu_items[intval($_menu_item_menu_item_parent)] ) ) {
906
- $_menu_item_menu_item_parent = $this->processed_menu_items[intval($_menu_item_menu_item_parent)];
907
- } else if ( $_menu_item_menu_item_parent ) {
908
- $this->menu_item_orphans[intval($item['post_id'])] = (int) $_menu_item_menu_item_parent;
909
- $_menu_item_menu_item_parent = 0;
910
  }
911
 
912
  // wp_update_nav_menu_item expects CSS classes as a space separated string
913
  $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
914
- if ( is_array( $_menu_item_classes ) )
915
  $_menu_item_classes = implode( ' ', $_menu_item_classes );
 
916
 
917
  $args = array(
918
- 'menu-item-object-id' => $_menu_item_object_id,
919
- 'menu-item-object' => $_menu_item_object,
920
- 'menu-item-parent-id' => $_menu_item_menu_item_parent,
921
- 'menu-item-position' => intval( $item['menu_order'] ),
922
- 'menu-item-type' => $_menu_item_type,
923
- 'menu-item-title' => $item['post_title'],
924
- 'menu-item-url' => $_menu_item_url,
925
  'menu-item-description' => $item['post_content'],
926
- 'menu-item-attr-title' => $item['post_excerpt'],
927
- 'menu-item-target' => $_menu_item_target,
928
- 'menu-item-classes' => $_menu_item_classes,
929
- 'menu-item-xfn' => $_menu_item_xfn,
930
- 'menu-item-status' => $item['status']
931
  );
932
 
933
  $id = wp_update_nav_menu_item( $menu_id, 0, $args );
934
- if ( $id && ! is_wp_error( $id ) )
935
- $this->processed_menu_items[intval($item['post_id'])] = (int) $id;
 
936
  }
937
 
938
  /**
@@ -943,22 +1007,29 @@ class WP_Import extends WP_Importer {
943
  * @return int|WP_Error Post ID on success, WP_Error otherwise
944
  */
945
  function process_attachment( $post, $url ) {
946
- if ( ! $this->fetch_attachments )
947
- return new WP_Error( 'attachment_processing_error',
948
- __( 'Fetching attachments is not enabled', 'wordpress-importer' ) );
 
 
 
949
 
950
  // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
951
- if ( preg_match( '|^/[\w\W]+$|', $url ) )
952
  $url = rtrim( $this->base_url, '/' ) . $url;
 
953
 
954
  $upload = $this->fetch_remote_file( $url, $post );
955
- if ( is_wp_error( $upload ) )
956
  return $upload;
 
957
 
958
- if ( $info = wp_check_filetype( $upload['file'] ) )
 
959
  $post['post_mime_type'] = $info['type'];
960
- else
961
- return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'wordpress-importer') );
 
962
 
963
  $post['guid'] = $upload['url'];
964
 
@@ -969,12 +1040,12 @@ class WP_Import extends WP_Importer {
969
  // remap resized image URLs, works by stripping the extension and remapping the URL stub.
970
  if ( preg_match( '!^image/!', $info['type'] ) ) {
971
  $parts = pathinfo( $url );
972
- $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
973
 
974
  $parts_new = pathinfo( $upload['url'] );
975
- $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
976
 
977
- $this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
978
  }
979
 
980
  return $post_id;
@@ -989,7 +1060,11 @@ class WP_Import extends WP_Importer {
989
  */
990
  function fetch_remote_file( $url, $post ) {
991
  // Extract the file name from the URL.
992
- $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
 
 
 
 
993
 
994
  if ( ! $file_name ) {
995
  $file_name = md5( $url );
@@ -1001,14 +1076,17 @@ class WP_Import extends WP_Importer {
1001
  }
1002
 
1003
  // Fetch the remote URL and write it to the placeholder file.
1004
- $remote_response = wp_safe_remote_get( $url, array(
1005
- 'timeout' => 300,
1006
- 'stream' => true,
1007
- 'filename' => $tmp_file_name,
1008
- 'headers' => array(
1009
- 'Accept-Encoding' => 'identity',
1010
- ),
1011
- ) );
 
 
 
1012
 
1013
  if ( is_wp_error( $remote_response ) ) {
1014
  @unlink( $tmp_file_name );
@@ -1044,25 +1122,25 @@ class WP_Import extends WP_Importer {
1044
  // Request failed.
1045
  if ( ! $headers ) {
1046
  @unlink( $tmp_file_name );
1047
- return new WP_Error( 'import_file_error', __('Remote server did not respond', 'wordpress-importer') );
1048
  }
1049
 
1050
  $filesize = (int) filesize( $tmp_file_name );
1051
 
1052
  if ( 0 === $filesize ) {
1053
  @unlink( $tmp_file_name );
1054
- return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'wordpress-importer') );
1055
  }
1056
 
1057
  if ( ! isset( $headers['content-encoding'] ) && isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
1058
  @unlink( $tmp_file_name );
1059
- return new WP_Error( 'import_file_error', __('Downloaded file has incorrect size', 'wordpress-importer' ) );
1060
  }
1061
 
1062
  $max_size = (int) $this->max_attachment_size();
1063
  if ( ! empty( $max_size ) && $filesize > $max_size ) {
1064
  @unlink( $tmp_file_name );
1065
- return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'wordpress-importer' ), size_format($max_size) ) );
1066
  }
1067
 
1068
  // Override file name with Content-Disposition header value.
@@ -1125,11 +1203,12 @@ class WP_Import extends WP_Importer {
1125
  );
1126
 
1127
  // keep track of the old and new urls so we can substitute them later
1128
- $this->url_remap[$url] = $upload['url'];
1129
- $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed?
1130
  // keep track of the destination if the remote url is redirected somewhere else
1131
- if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url )
1132
- $this->url_remap[$headers['x-final-location']] = $upload['url'];
 
1133
 
1134
  return $upload;
1135
  }
@@ -1146,11 +1225,14 @@ class WP_Import extends WP_Importer {
1146
 
1147
  // find parents for post orphans
1148
  foreach ( $this->post_orphans as $child_id => $parent_id ) {
1149
- $local_child_id = $local_parent_id = false;
1150
- if ( isset( $this->processed_posts[$child_id] ) )
1151
- $local_child_id = $this->processed_posts[$child_id];
1152
- if ( isset( $this->processed_posts[$parent_id] ) )
1153
- $local_parent_id = $this->processed_posts[$parent_id];
 
 
 
1154
 
1155
  if ( $local_child_id && $local_parent_id ) {
1156
  $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
@@ -1160,19 +1242,24 @@ class WP_Import extends WP_Importer {
1160
 
1161
  // all other posts/terms are imported, retry menu items with missing associated object
1162
  $missing_menu_items = $this->missing_menu_items;
1163
- foreach ( $missing_menu_items as $item )
1164
  $this->process_menu_item( $item );
 
1165
 
1166
  // find parents for menu item orphans
1167
  foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
1168
- $local_child_id = $local_parent_id = 0;
1169
- if ( isset( $this->processed_menu_items[$child_id] ) )
1170
- $local_child_id = $this->processed_menu_items[$child_id];
1171
- if ( isset( $this->processed_menu_items[$parent_id] ) )
1172
- $local_parent_id = $this->processed_menu_items[$parent_id];
 
 
 
1173
 
1174
- if ( $local_child_id && $local_parent_id )
1175
  update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
 
1176
  }
1177
  }
1178
 
@@ -1182,13 +1269,13 @@ class WP_Import extends WP_Importer {
1182
  function backfill_attachment_urls() {
1183
  global $wpdb;
1184
  // make sure we do the longest urls first, in case one is a substring of another
1185
- uksort( $this->url_remap, array(&$this, 'cmpr_strlen') );
1186
 
1187
  foreach ( $this->url_remap as $from_url => $to_url ) {
1188
  // remap urls in post_content
1189
- $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );
1190
  // remap enclosure urls
1191
- $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) );
1192
  }
1193
  }
1194
 
@@ -1198,11 +1285,12 @@ class WP_Import extends WP_Importer {
1198
  function remap_featured_images() {
1199
  // cycle through posts that have a featured image
1200
  foreach ( $this->featured_images as $post_id => $value ) {
1201
- if ( isset( $this->processed_posts[$value] ) ) {
1202
- $new_id = $this->processed_posts[$value];
1203
  // only update if there's a difference
1204
- if ( $new_id != $value )
1205
  update_post_meta( $post_id, '_thumbnail_id', $new_id );
 
1206
  }
1207
  }
1208
  }
@@ -1223,10 +1311,10 @@ class WP_Import extends WP_Importer {
1223
  echo '<div class="wrap">';
1224
  echo '<h2>' . __( 'Import WordPress', 'wordpress-importer' ) . '</h2>';
1225
 
1226
- $updates = get_plugin_updates();
1227
- $basename = plugin_basename(__FILE__);
1228
- if ( isset( $updates[$basename] ) ) {
1229
- $update = $updates[$basename];
1230
  echo '<div class="error"><p><strong>';
1231
  printf( __( 'A new version of this importer is available. Please update to version %s to ensure compatibility with newer export files.', 'wordpress-importer' ), $update->update->new_version );
1232
  echo '</strong></p></div>';
@@ -1243,8 +1331,8 @@ class WP_Import extends WP_Importer {
1243
  */
1244
  function greet() {
1245
  echo '<div class="narrow">';
1246
- echo '<p>'.__( 'Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import the posts, pages, comments, custom fields, categories, and tags into this site.', 'wordpress-importer' ).'</p>';
1247
- echo '<p>'.__( 'Choose a WXR (.xml) file to upload, then click Upload file and import.', 'wordpress-importer' ).'</p>';
1248
  wp_import_upload_form( 'admin.php?import=wordpress&amp;step=1' );
1249
  echo '</div>';
1250
  }
@@ -1258,8 +1346,9 @@ class WP_Import extends WP_Importer {
1258
  function is_valid_meta_key( $key ) {
1259
  // skip attachment metadata since we'll regenerate it from scratch
1260
  // skip _edit_lock as not relevant for import
1261
- if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) )
1262
  return false;
 
1263
  return $key;
1264
  }
1265
 
@@ -1304,7 +1393,7 @@ class WP_Import extends WP_Importer {
1304
 
1305
  // return the difference in length between two strings
1306
  function cmpr_strlen( $a, $b ) {
1307
- return strlen($b) - strlen($a);
1308
  }
1309
 
1310
  /**
16
 
17
  // information to import from WXR file
18
  var $version;
19
+ var $authors = array();
20
+ var $posts = array();
21
+ var $terms = array();
22
  var $categories = array();
23
+ var $tags = array();
24
+ var $base_url = '';
25
 
26
  // mappings from old information to new
27
+ var $processed_authors = array();
28
+ var $author_mapping = array();
29
+ var $processed_terms = array();
30
+ var $processed_posts = array();
31
+ var $post_orphans = array();
32
  var $processed_menu_items = array();
33
+ var $menu_item_orphans = array();
34
+ var $missing_menu_items = array();
35
 
36
  var $fetch_attachments = false;
37
+ var $url_remap = array();
38
+ var $featured_images = array();
39
 
40
  /**
41
  * Registered callback function for the WordPress Importer
52
  break;
53
  case 1:
54
  check_admin_referer( 'import-upload' );
55
+ if ( $this->handle_upload() ) {
56
  $this->import_options();
57
+ }
58
  break;
59
  case 2:
60
  check_admin_referer( 'import-wordpress' );
61
  $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() );
62
+ $this->id = (int) $_POST['import_id'];
63
+ $file = get_attached_file( $this->id );
64
+ set_time_limit( 0 );
65
  $this->import( $file );
66
  break;
67
  }
103
  * @param string $file Path to the WXR file for importing
104
  */
105
  function import_start( $file ) {
106
+ if ( ! is_file( $file ) ) {
107
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
108
  echo __( 'The file does not exist, please try again.', 'wordpress-importer' ) . '</p>';
109
  $this->footer();
121
 
122
  $this->version = $import_data['version'];
123
  $this->get_authors_from_import( $import_data );
124
+ $this->posts = $import_data['posts'];
125
+ $this->terms = $import_data['terms'];
126
  $this->categories = $import_data['categories'];
127
+ $this->tags = $import_data['tags'];
128
+ $this->base_url = esc_url( $import_data['base_url'] );
129
 
130
  wp_defer_term_counting( true );
131
  wp_defer_comment_counting( true );
167
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
168
  echo esc_html( $file['error'] ) . '</p>';
169
  return false;
170
+ } elseif ( ! file_exists( $file['file'] ) ) {
171
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
172
  printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'wordpress-importer' ), esc_html( $file['file'] ) );
173
  echo '</p>';
174
  return false;
175
  }
176
 
177
+ $this->id = (int) $file['id'];
178
  $import_data = $this->parse( $file['file'] );
179
  if ( is_wp_error( $import_data ) ) {
180
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
185
  $this->version = $import_data['version'];
186
  if ( $this->version > $this->max_wxr_version ) {
187
  echo '<div class="error"><p><strong>';
188
+ printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'wordpress-importer' ), esc_html( $import_data['version'] ) );
189
  echo '</strong></p></div>';
190
  }
191
 
205
  function get_authors_from_import( $import_data ) {
206
  if ( ! empty( $import_data['authors'] ) ) {
207
  $this->authors = $import_data['authors'];
208
+ // no author information, grab it from the posts
209
  } else {
210
  foreach ( $import_data['posts'] as $post ) {
211
  $login = sanitize_user( $post['post_author'], true );
215
  continue;
216
  }
217
 
218
+ if ( ! isset( $this->authors[ $login ] ) ) {
219
+ $this->authors[ $login ] = array(
220
+ 'author_login' => $login,
221
+ 'author_display_name' => $post['post_author'],
222
  );
223
+ }
224
  }
225
  }
226
  }
231
  */
232
  function import_options() {
233
  $j = 0;
234
+ // phpcs:disable Generic.WhiteSpace.ScopeIndent.Incorrect
235
+ ?>
236
  <form action="<?php echo admin_url( 'admin.php?import=wordpress&amp;step=2' ); ?>" method="post">
237
  <?php wp_nonce_field( 'import-wordpress' ); ?>
238
  <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
241
  <h3><?php _e( 'Assign Authors', 'wordpress-importer' ); ?></h3>
242
  <p><?php _e( 'To make it simpler for you to edit and save the imported content, you may want to reassign the author of the imported item to an existing user of this site, such as your primary administrator account.', 'wordpress-importer' ); ?></p>
243
  <?php if ( $this->allow_create_users() ) : ?>
244
+ <p><?php printf( __( 'If a new user is created by WordPress, a new password will be randomly generated and the new user&#8217;s role will be set as %s. Manually changing the new user&#8217;s details will be necessary.', 'wordpress-importer' ), esc_html( get_option( 'default_role' ) ) ); ?></p>
245
  <?php endif; ?>
246
  <ol id="authors">
247
  <?php foreach ( $this->authors as $author ) : ?>
260
 
261
  <p class="submit"><input type="submit" class="button" value="<?php esc_attr_e( 'Submit', 'wordpress-importer' ); ?>" /></p>
262
  </form>
263
+ <?php
264
+ // phpcs:enable Generic.WhiteSpace.ScopeIndent.Incorrect
265
  }
266
 
267
  /**
274
  function author_select( $n, $author ) {
275
  _e( 'Import author:', 'wordpress-importer' );
276
  echo ' <strong>' . esc_html( $author['author_display_name'] );
277
+ if ( '1.0' != $this->version ) {
278
+ echo ' (' . esc_html( $author['author_login'] ) . ')';
279
+ }
280
  echo '</strong><br />';
281
 
282
+ if ( '1.0' != $this->version ) {
283
  echo '<div style="margin-left:18px">';
284
+ }
285
 
286
  $create_users = $this->allow_create_users();
287
  if ( $create_users ) {
288
+ echo '<label for="user_new_' . $n . '">';
289
+ if ( '1.0' != $this->version ) {
290
  _e( 'or create new user with login name:', 'wordpress-importer' );
291
  $value = '';
292
  } else {
295
  }
296
  echo '</label>';
297
 
298
+ echo ' <input type="text" id="user_new_' . $n . '" name="user_new[' . $n . ']" value="' . $value . '" /><br />';
299
  }
300
 
301
+ echo '<label for="imported_authors_' . $n . '">';
302
+ if ( ! $create_users && '1.0' == $this->version ) {
303
  _e( 'assign posts to an existing user:', 'wordpress-importer' );
304
  } else {
305
  _e( 'or assign posts to an existing user:', 'wordpress-importer' );
306
  }
307
  echo '</label>';
308
 
309
+ echo ' ' . wp_dropdown_users(
310
+ array(
311
+ 'name' => "user_map[$n]",
312
+ 'id' => 'imported_authors_' . $n,
313
+ 'multi' => true,
314
+ 'show_option_all' => __( '- Select -', 'wordpress-importer' ),
315
+ 'show' => 'display_name_with_login',
316
+ 'echo' => 0,
317
+ )
318
+ );
319
 
320
+ echo '<input type="hidden" name="imported_authors[' . $n . ']" value="' . esc_attr( $author['author_login'] ) . '" />';
321
 
322
+ if ( '1.0' != $this->version ) {
323
  echo '</div>';
324
+ }
325
  }
326
 
327
  /**
330
  * or falls back to the current user in case of error with either of the previous
331
  */
332
  function get_author_mapping() {
333
+ if ( ! isset( $_POST['imported_authors'] ) ) {
334
  return;
335
+ }
336
 
337
  $create_users = $this->allow_create_users();
338
 
339
  foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
340
  // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
341
  $santized_old_login = sanitize_user( $old_login, true );
342
+ $old_id = isset( $this->authors[ $old_login ]['author_id'] ) ? intval( $this->authors[ $old_login ]['author_id'] ) : false;
343
 
344
+ if ( ! empty( $_POST['user_map'][ $i ] ) ) {
345
+ $user = get_userdata( intval( $_POST['user_map'][ $i ] ) );
346
  if ( isset( $user->ID ) ) {
347
+ if ( $old_id ) {
348
+ $this->processed_authors[ $old_id ] = $user->ID;
349
+ }
350
+ $this->author_mapping[ $santized_old_login ] = $user->ID;
351
  }
352
+ } elseif ( $create_users ) {
353
+ if ( ! empty( $_POST['user_new'][ $i ] ) ) {
354
+ $user_id = wp_create_user( $_POST['user_new'][ $i ], wp_generate_password() );
355
+ } elseif ( '1.0' != $this->version ) {
356
  $user_data = array(
357
+ 'user_login' => $old_login,
358
+ 'user_pass' => wp_generate_password(),
359
+ 'user_email' => isset( $this->authors[ $old_login ]['author_email'] ) ? $this->authors[ $old_login ]['author_email'] : '',
360
+ 'display_name' => $this->authors[ $old_login ]['author_display_name'],
361
+ 'first_name' => isset( $this->authors[ $old_login ]['author_first_name'] ) ? $this->authors[ $old_login ]['author_first_name'] : '',
362
+ 'last_name' => isset( $this->authors[ $old_login ]['author_last_name'] ) ? $this->authors[ $old_login ]['author_last_name'] : '',
363
  );
364
+ $user_id = wp_insert_user( $user_data );
365
  }
366
 
367
  if ( ! is_wp_error( $user_id ) ) {
368
+ if ( $old_id ) {
369
+ $this->processed_authors[ $old_id ] = $user_id;
370
+ }
371
+ $this->author_mapping[ $santized_old_login ] = $user_id;
372
  } else {
373
+ printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html( $this->authors[ $old_login ]['author_display_name'] ) );
374
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
375
  echo ' ' . $user_id->get_error_message();
376
+ }
377
  echo '<br />';
378
  }
379
  }
380
 
381
  // failsafe: if the user_id was invalid, default to the current user
382
+ if ( ! isset( $this->author_mapping[ $santized_old_login ] ) ) {
383
+ if ( $old_id ) {
384
+ $this->processed_authors[ $old_id ] = (int) get_current_user_id();
385
+ }
386
+ $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
387
  }
388
  }
389
  }
396
  function process_categories() {
397
  $this->categories = apply_filters( 'wp_import_categories', $this->categories );
398
 
399
+ if ( empty( $this->categories ) ) {
400
  return;
401
+ }
402
 
403
  foreach ( $this->categories as $cat ) {
404
  // if the category already exists leave it alone
405
  $term_id = term_exists( $cat['category_nicename'], 'category' );
406
  if ( $term_id ) {
407
+ if ( is_array( $term_id ) ) {
408
+ $term_id = $term_id['term_id'];
409
+ }
410
+ if ( isset( $cat['term_id'] ) ) {
411
+ $this->processed_terms[ intval( $cat['term_id'] ) ] = (int) $term_id;
412
+ }
413
  continue;
414
  }
415
 
423
  'category_description' => wp_slash( $description ),
424
  );
425
 
426
+ $id = wp_insert_category( $data, true );
427
  if ( ! is_wp_error( $id ) && $id > 0 ) {
428
+ if ( isset( $cat['term_id'] ) ) {
429
+ $this->processed_terms[ intval( $cat['term_id'] ) ] = $id;
430
+ }
431
  } else {
432
+ printf( __( 'Failed to import category %s', 'wordpress-importer' ), esc_html( $cat['category_nicename'] ) );
433
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
434
  echo ': ' . $id->get_error_message();
435
+ }
436
  echo '<br />';
437
  continue;
438
  }
451
  function process_tags() {
452
  $this->tags = apply_filters( 'wp_import_tags', $this->tags );
453
 
454
+ if ( empty( $this->tags ) ) {
455
  return;
456
+ }
457
 
458
  foreach ( $this->tags as $tag ) {
459
  // if the tag already exists leave it alone
460
  $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
461
  if ( $term_id ) {
462
+ if ( is_array( $term_id ) ) {
463
+ $term_id = $term_id['term_id'];
464
+ }
465
+ if ( isset( $tag['term_id'] ) ) {
466
+ $this->processed_terms[ intval( $tag['term_id'] ) ] = (int) $term_id;
467
+ }
468
  continue;
469
  }
470
 
476
 
477
  $id = wp_insert_term( wp_slash( $tag['tag_name'] ), 'post_tag', $args );
478
  if ( ! is_wp_error( $id ) ) {
479
+ if ( isset( $tag['term_id'] ) ) {
480
+ $this->processed_terms[ intval( $tag['term_id'] ) ] = $id['term_id'];
481
+ }
482
  } else {
483
+ printf( __( 'Failed to import post tag %s', 'wordpress-importer' ), esc_html( $tag['tag_name'] ) );
484
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
485
  echo ': ' . $id->get_error_message();
486
+ }
487
  echo '<br />';
488
  continue;
489
  }
502
  function process_terms() {
503
  $this->terms = apply_filters( 'wp_import_terms', $this->terms );
504
 
505
+ if ( empty( $this->terms ) ) {
506
  return;
507
+ }
508
 
509
  foreach ( $this->terms as $term ) {
510
  // if the term already exists in the correct taxonomy leave it alone
511
  $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
512
  if ( $term_id ) {
513
+ if ( is_array( $term_id ) ) {
514
+ $term_id = $term_id['term_id'];
515
+ }
516
+ if ( isset( $term['term_id'] ) ) {
517
+ $this->processed_terms[ intval( $term['term_id'] ) ] = (int) $term_id;
518
+ }
519
  continue;
520
  }
521
 
532
  $args = array(
533
  'slug' => $term['slug'],
534
  'description' => wp_slash( $description ),
535
+ 'parent' => (int) $parent,
536
  );
537
 
538
  $id = wp_insert_term( wp_slash( $term['term_name'] ), $term['term_taxonomy'], $args );
539
  if ( ! is_wp_error( $id ) ) {
540
+ if ( isset( $term['term_id'] ) ) {
541
+ $this->processed_terms[ intval( $term['term_id'] ) ] = $id['term_id'];
542
+ }
543
  } else {
544
+ printf( __( 'Failed to import %1$s %2$s', 'wordpress-importer' ), esc_html( $term['term_taxonomy'] ), esc_html( $term['term_name'] ) );
545
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
546
  echo ': ' . $id->get_error_message();
547
+ }
548
  echo '<br />';
549
  continue;
550
  }
564
  * @param int $term_id ID of the newly created term.
565
  */
566
  protected function process_termmeta( $term, $term_id ) {
 
 
 
 
567
  if ( ! isset( $term['termmeta'] ) ) {
568
  $term['termmeta'] = array();
569
  }
631
  $post = apply_filters( 'wp_import_post_data_raw', $post );
632
 
633
  if ( ! post_type_exists( $post['post_type'] ) ) {
634
+ printf(
635
+ __( 'Failed to import &#8220;%1$s&#8221;: Invalid post type %2$s', 'wordpress-importer' ),
636
+ esc_html( $post['post_title'] ),
637
+ esc_html( $post['post_type'] )
638
+ );
639
  echo '<br />';
640
  do_action( 'wp_import_post_exists', $post );
641
  continue;
642
  }
643
 
644
+ if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) {
645
  continue;
646
+ }
647
 
648
+ if ( 'auto-draft' == $post['status'] ) {
649
  continue;
650
+ }
651
 
652
  if ( 'nav_menu_item' == $post['post_type'] ) {
653
  $this->process_menu_item( $post );
673
  $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
674
 
675
  if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
676
+ printf( __( '%1$s &#8220;%2$s&#8221; already exists.', 'wordpress-importer' ), $post_type_object->labels->singular_name, esc_html( $post['post_title'] ) );
677
  echo '<br />';
678
+ $comment_post_id = $post_exists;
679
+ $post_id = $post_exists;
680
  $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
681
  } else {
682
  $post_parent = (int) $post['post_parent'];
683
  if ( $post_parent ) {
684
  // if we already know the parent, map it to the new local ID
685
+ if ( isset( $this->processed_posts[ $post_parent ] ) ) {
686
+ $post_parent = $this->processed_posts[ $post_parent ];
687
+ // otherwise record the parent for later
688
  } else {
689
+ $this->post_orphans[ intval( $post['post_id'] ) ] = $post_parent;
690
+ $post_parent = 0;
691
  }
692
  }
693
 
694
  // map the post author
695
  $author = sanitize_user( $post['post_author'], true );
696
+ if ( isset( $this->author_mapping[ $author ] ) ) {
697
+ $author = $this->author_mapping[ $author ];
698
+ } else {
699
  $author = (int) get_current_user_id();
700
+ }
701
 
702
  $postdata = array(
703
+ 'import_id' => $post['post_id'],
704
+ 'post_author' => $author,
705
+ 'post_date' => $post['post_date'],
706
+ 'post_date_gmt' => $post['post_date_gmt'],
707
+ 'post_content' => $post['post_content'],
708
+ 'post_excerpt' => $post['post_excerpt'],
709
+ 'post_title' => $post['post_title'],
710
+ 'post_status' => $post['status'],
711
+ 'post_name' => $post['post_name'],
712
+ 'comment_status' => $post['comment_status'],
713
+ 'ping_status' => $post['ping_status'],
714
+ 'guid' => $post['guid'],
715
+ 'post_parent' => $post_parent,
716
+ 'menu_order' => $post['menu_order'],
717
+ 'post_type' => $post['post_type'],
718
+ 'post_password' => $post['post_password'],
719
  );
720
 
721
+ $original_post_id = $post['post_id'];
722
+ $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
723
 
724
  $postdata = wp_slash( $postdata );
725
 
726
  if ( 'attachment' == $postdata['post_type'] ) {
727
+ $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid'];
728
 
729
  // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
730
  // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
731
  $postdata['upload_date'] = $post['post_date'];
732
  if ( isset( $post['postmeta'] ) ) {
733
+ foreach ( $post['postmeta'] as $meta ) {
734
+ if ( '_wp_attached_file' == $meta['key'] ) {
735
+ if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) {
736
  $postdata['upload_date'] = $matches[0];
737
+ }
738
  break;
739
  }
740
  }
741
  }
742
 
743
+ $comment_post_id = $this->process_attachment( $postdata, $remote_url );
744
+ $post_id = $comment_post_id;
745
  } else {
746
+ $comment_post_id = wp_insert_post( $postdata, true );
747
+ $post_id = $comment_post_id;
748
+ do_action( 'wp_import_insert_post', $post_id, $original_post_id, $postdata, $post );
749
  }
750
 
751
  if ( is_wp_error( $post_id ) ) {
752
+ printf(
753
+ __( 'Failed to import %1$s &#8220;%2$s&#8221;', 'wordpress-importer' ),
754
+ $post_type_object->labels->singular_name,
755
+ esc_html( $post['post_title'] )
756
+ );
757
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
758
  echo ': ' . $post_id->get_error_message();
759
+ }
760
  echo '<br />';
761
  continue;
762
  }
763
 
764
+ if ( 1 == $post['is_sticky'] ) {
765
  stick_post( $post_id );
766
+ }
767
  }
768
 
769
  // map pre-import ID to local ID
770
+ $this->processed_posts[ intval( $post['post_id'] ) ] = (int) $post_id;
771
 
772
+ if ( ! isset( $post['terms'] ) ) {
773
  $post['terms'] = array();
774
+ }
775
 
776
  $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
777
 
780
  $terms_to_set = array();
781
  foreach ( $post['terms'] as $term ) {
782
  // back compat with WXR 1.0 map 'tag' to 'post_tag'
783
+ $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
784
  $term_exists = term_exists( $term['slug'], $taxonomy );
785
+ $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
786
  if ( ! $term_id ) {
787
  $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
788
  if ( ! is_wp_error( $t ) ) {
789
  $term_id = $t['term_id'];
790
  do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
791
  } else {
792
+ printf( __( 'Failed to import %1$s %2$s', 'wordpress-importer' ), esc_html( $taxonomy ), esc_html( $term['name'] ) );
793
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
794
  echo ': ' . $t->get_error_message();
795
+ }
796
  echo '<br />';
797
  do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
798
  continue;
799
  }
800
  }
801
+ $terms_to_set[ $taxonomy ][] = intval( $term_id );
802
  }
803
 
804
  foreach ( $terms_to_set as $tax => $ids ) {
808
  unset( $post['terms'], $terms_to_set );
809
  }
810
 
811
+ if ( ! isset( $post['comments'] ) ) {
812
  $post['comments'] = array();
813
+ }
814
 
815
  $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
816
 
817
  // add/update comments
818
  if ( ! empty( $post['comments'] ) ) {
819
+ $num_comments = 0;
820
  $inserted_comments = array();
821
  foreach ( $post['comments'] as $comment ) {
822
+ $comment_id = $comment['comment_id'];
823
+ $newcomments[ $comment_id ]['comment_post_ID'] = $comment_post_id;
824
+ $newcomments[ $comment_id ]['comment_author'] = $comment['comment_author'];
825
+ $newcomments[ $comment_id ]['comment_author_email'] = $comment['comment_author_email'];
826
+ $newcomments[ $comment_id ]['comment_author_IP'] = $comment['comment_author_IP'];
827
+ $newcomments[ $comment_id ]['comment_author_url'] = $comment['comment_author_url'];
828
+ $newcomments[ $comment_id ]['comment_date'] = $comment['comment_date'];
829
+ $newcomments[ $comment_id ]['comment_date_gmt'] = $comment['comment_date_gmt'];
830
+ $newcomments[ $comment_id ]['comment_content'] = $comment['comment_content'];
831
+ $newcomments[ $comment_id ]['comment_approved'] = $comment['comment_approved'];
832
+ $newcomments[ $comment_id ]['comment_type'] = $comment['comment_type'];
833
+ $newcomments[ $comment_id ]['comment_parent'] = $comment['comment_parent'];
834
+ $newcomments[ $comment_id ]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
835
+ if ( isset( $this->processed_authors[ $comment['comment_user_id'] ] ) ) {
836
+ $newcomments[ $comment_id ]['user_id'] = $this->processed_authors[ $comment['comment_user_id'] ];
837
+ }
838
  }
839
  ksort( $newcomments );
840
 
841
  foreach ( $newcomments as $key => $comment ) {
842
  // if this is a new post we can skip the comment_exists() check
843
  if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
844
+ if ( isset( $inserted_comments[ $comment['comment_parent'] ] ) ) {
845
  $comment['comment_parent'] = $inserted_comments[ $comment['comment_parent'] ];
846
  }
847
 
851
 
852
  $inserted_comments[ $key ] = wp_insert_comment( $comment_data );
853
 
854
+ do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $comment_post_id, $post );
855
 
856
+ foreach ( $comment['commentmeta'] as $meta ) {
857
  $value = maybe_unserialize( $meta['value'] );
858
 
859
  add_comment_meta( $inserted_comments[ $key ], wp_slash( $meta['key'] ), wp_slash_strings_only( $value ) );
865
  unset( $newcomments, $inserted_comments, $post['comments'] );
866
  }
867
 
868
+ if ( ! isset( $post['postmeta'] ) ) {
869
  $post['postmeta'] = array();
870
+ }
871
 
872
  $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
873
 
874
  // add/update post meta
875
  if ( ! empty( $post['postmeta'] ) ) {
876
  foreach ( $post['postmeta'] as $meta ) {
877
+ $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
878
  $value = false;
879
 
880
  if ( '_edit_last' == $key ) {
881
+ if ( isset( $this->processed_authors[ intval( $meta['value'] ) ] ) ) {
882
+ $value = $this->processed_authors[ intval( $meta['value'] ) ];
883
+ } else {
884
  $key = false;
885
+ }
886
  }
887
 
888
  if ( $key ) {
896
  do_action( 'import_post_meta', $post_id, $key, $value );
897
 
898
  // if the post has a featured image, take note of this in case of remap
899
+ if ( '_thumbnail_id' == $key ) {
900
+ $this->featured_images[ $post_id ] = (int) $value;
901
+ }
902
  }
903
  }
904
  }
919
  */
920
  function process_menu_item( $item ) {
921
  // skip draft, orphaned menu items
922
+ if ( 'draft' == $item['status'] ) {
923
  return;
924
+ }
925
 
926
  $menu_slug = false;
927
+ if ( isset( $item['terms'] ) ) {
928
  // loop through terms, assume first nav_menu term is correct menu
929
  foreach ( $item['terms'] as $term ) {
930
  if ( 'nav_menu' == $term['domain'] ) {
950
  $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
951
  }
952
 
953
+ foreach ( $item['postmeta'] as $meta ) {
954
  ${$meta['key']} = $meta['value'];
955
+ }
956
 
957
+ if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[ intval( $_menu_item_object_id ) ] ) ) {
958
+ $_menu_item_object_id = $this->processed_terms[ intval( $_menu_item_object_id ) ];
959
+ } elseif ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[ intval( $_menu_item_object_id ) ] ) ) {
960
+ $_menu_item_object_id = $this->processed_posts[ intval( $_menu_item_object_id ) ];
961
+ } elseif ( 'custom' != $_menu_item_type ) {
962
  // associated object is missing or not imported yet, we'll retry later
963
  $this->missing_menu_items[] = $item;
964
  return;
965
  }
966
 
967
+ if ( isset( $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ] ) ) {
968
+ $_menu_item_menu_item_parent = $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ];
969
+ } elseif ( $_menu_item_menu_item_parent ) {
970
+ $this->menu_item_orphans[ intval( $item['post_id'] ) ] = (int) $_menu_item_menu_item_parent;
971
+ $_menu_item_menu_item_parent = 0;
972
  }
973
 
974
  // wp_update_nav_menu_item expects CSS classes as a space separated string
975
  $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
976
+ if ( is_array( $_menu_item_classes ) ) {
977
  $_menu_item_classes = implode( ' ', $_menu_item_classes );
978
+ }
979
 
980
  $args = array(
981
+ 'menu-item-object-id' => $_menu_item_object_id,
982
+ 'menu-item-object' => $_menu_item_object,
983
+ 'menu-item-parent-id' => $_menu_item_menu_item_parent,
984
+ 'menu-item-position' => intval( $item['menu_order'] ),
985
+ 'menu-item-type' => $_menu_item_type,
986
+ 'menu-item-title' => $item['post_title'],
987
+ 'menu-item-url' => $_menu_item_url,
988
  'menu-item-description' => $item['post_content'],
989
+ 'menu-item-attr-title' => $item['post_excerpt'],
990
+ 'menu-item-target' => $_menu_item_target,
991
+ 'menu-item-classes' => $_menu_item_classes,
992
+ 'menu-item-xfn' => $_menu_item_xfn,
993
+ 'menu-item-status' => $item['status'],
994
  );
995
 
996
  $id = wp_update_nav_menu_item( $menu_id, 0, $args );
997
+ if ( $id && ! is_wp_error( $id ) ) {
998
+ $this->processed_menu_items[ intval( $item['post_id'] ) ] = (int) $id;
999
+ }
1000
  }
1001
 
1002
  /**
1007
  * @return int|WP_Error Post ID on success, WP_Error otherwise
1008
  */
1009
  function process_attachment( $post, $url ) {
1010
+ if ( ! $this->fetch_attachments ) {
1011
+ return new WP_Error(
1012
+ 'attachment_processing_error',
1013
+ __( 'Fetching attachments is not enabled', 'wordpress-importer' )
1014
+ );
1015
+ }
1016
 
1017
  // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
1018
+ if ( preg_match( '|^/[\w\W]+$|', $url ) ) {
1019
  $url = rtrim( $this->base_url, '/' ) . $url;
1020
+ }
1021
 
1022
  $upload = $this->fetch_remote_file( $url, $post );
1023
+ if ( is_wp_error( $upload ) ) {
1024
  return $upload;
1025
+ }
1026
 
1027
+ $info = wp_check_filetype( $upload['file'] );
1028
+ if ( $info ) {
1029
  $post['post_mime_type'] = $info['type'];
1030
+ } else {
1031
+ return new WP_Error( 'attachment_processing_error', __( 'Invalid file type', 'wordpress-importer' ) );
1032
+ }
1033
 
1034
  $post['guid'] = $upload['url'];
1035
 
1040
  // remap resized image URLs, works by stripping the extension and remapping the URL stub.
1041
  if ( preg_match( '!^image/!', $info['type'] ) ) {
1042
  $parts = pathinfo( $url );
1043
+ $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
1044
 
1045
  $parts_new = pathinfo( $upload['url'] );
1046
+ $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
1047
 
1048
+ $this->url_remap[ $parts['dirname'] . '/' . $name ] = $parts_new['dirname'] . '/' . $name_new;
1049
  }
1050
 
1051
  return $post_id;
1060
  */
1061
  function fetch_remote_file( $url, $post ) {
1062
  // Extract the file name from the URL.
1063
+ $path = parse_url( $url, PHP_URL_PATH );
1064
+ $file_name = '';
1065
+ if ( is_string( $path ) ) {
1066
+ $file_name = basename( $path );
1067
+ }
1068
 
1069
  if ( ! $file_name ) {
1070
  $file_name = md5( $url );
1076
  }
1077
 
1078
  // Fetch the remote URL and write it to the placeholder file.
1079
+ $remote_response = wp_safe_remote_get(
1080
+ $url,
1081
+ array(
1082
+ 'timeout' => 300,
1083
+ 'stream' => true,
1084
+ 'filename' => $tmp_file_name,
1085
+ 'headers' => array(
1086
+ 'Accept-Encoding' => 'identity',
1087
+ ),
1088
+ )
1089
+ );
1090
 
1091
  if ( is_wp_error( $remote_response ) ) {
1092
  @unlink( $tmp_file_name );
1122
  // Request failed.
1123
  if ( ! $headers ) {
1124
  @unlink( $tmp_file_name );
1125
+ return new WP_Error( 'import_file_error', __( 'Remote server did not respond', 'wordpress-importer' ) );
1126
  }
1127
 
1128
  $filesize = (int) filesize( $tmp_file_name );
1129
 
1130
  if ( 0 === $filesize ) {
1131
  @unlink( $tmp_file_name );
1132
+ return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'wordpress-importer' ) );
1133
  }
1134
 
1135
  if ( ! isset( $headers['content-encoding'] ) && isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
1136
  @unlink( $tmp_file_name );
1137
+ return new WP_Error( 'import_file_error', __( 'Downloaded file has incorrect size', 'wordpress-importer' ) );
1138
  }
1139
 
1140
  $max_size = (int) $this->max_attachment_size();
1141
  if ( ! empty( $max_size ) && $filesize > $max_size ) {
1142
  @unlink( $tmp_file_name );
1143
+ return new WP_Error( 'import_file_error', sprintf( __( 'Remote file is too large, limit is %s', 'wordpress-importer' ), size_format( $max_size ) ) );
1144
  }
1145
 
1146
  // Override file name with Content-Disposition header value.
1203
  );
1204
 
1205
  // keep track of the old and new urls so we can substitute them later
1206
+ $this->url_remap[ $url ] = $upload['url'];
1207
+ $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1208
  // keep track of the destination if the remote url is redirected somewhere else
1209
+ if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] != $url ) {
1210
+ $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1211
+ }
1212
 
1213
  return $upload;
1214
  }
1225
 
1226
  // find parents for post orphans
1227
  foreach ( $this->post_orphans as $child_id => $parent_id ) {
1228
+ $local_child_id = false;
1229
+ $local_parent_id = false;
1230
+ if ( isset( $this->processed_posts[ $child_id ] ) ) {
1231
+ $local_child_id = $this->processed_posts[ $child_id ];
1232
+ }
1233
+ if ( isset( $this->processed_posts[ $parent_id ] ) ) {
1234
+ $local_parent_id = $this->processed_posts[ $parent_id ];
1235
+ }
1236
 
1237
  if ( $local_child_id && $local_parent_id ) {
1238
  $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
1242
 
1243
  // all other posts/terms are imported, retry menu items with missing associated object
1244
  $missing_menu_items = $this->missing_menu_items;
1245
+ foreach ( $missing_menu_items as $item ) {
1246
  $this->process_menu_item( $item );
1247
+ }
1248
 
1249
  // find parents for menu item orphans
1250
  foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
1251
+ $local_child_id = 0;
1252
+ $local_parent_id = 0;
1253
+ if ( isset( $this->processed_menu_items[ $child_id ] ) ) {
1254
+ $local_child_id = $this->processed_menu_items[ $child_id ];
1255
+ }
1256
+ if ( isset( $this->processed_menu_items[ $parent_id ] ) ) {
1257
+ $local_parent_id = $this->processed_menu_items[ $parent_id ];
1258
+ }
1259
 
1260
+ if ( $local_child_id && $local_parent_id ) {
1261
  update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
1262
+ }
1263
  }
1264
  }
1265
 
1269
  function backfill_attachment_urls() {
1270
  global $wpdb;
1271
  // make sure we do the longest urls first, in case one is a substring of another
1272
+ uksort( $this->url_remap, array( &$this, 'cmpr_strlen' ) );
1273
 
1274
  foreach ( $this->url_remap as $from_url => $to_url ) {
1275
  // remap urls in post_content
1276
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url ) );
1277
  // remap enclosure urls
1278
+ $result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url ) );
1279
  }
1280
  }
1281
 
1285
  function remap_featured_images() {
1286
  // cycle through posts that have a featured image
1287
  foreach ( $this->featured_images as $post_id => $value ) {
1288
+ if ( isset( $this->processed_posts[ $value ] ) ) {
1289
+ $new_id = $this->processed_posts[ $value ];
1290
  // only update if there's a difference
1291
+ if ( $new_id != $value ) {
1292
  update_post_meta( $post_id, '_thumbnail_id', $new_id );
1293
+ }
1294
  }
1295
  }
1296
  }
1311
  echo '<div class="wrap">';
1312
  echo '<h2>' . __( 'Import WordPress', 'wordpress-importer' ) . '</h2>';
1313
 
1314
+ $updates = get_plugin_updates();
1315
+ $basename = plugin_basename( __FILE__ );
1316
+ if ( isset( $updates[ $basename ] ) ) {
1317
+ $update = $updates[ $basename ];
1318
  echo '<div class="error"><p><strong>';
1319
  printf( __( 'A new version of this importer is available. Please update to version %s to ensure compatibility with newer export files.', 'wordpress-importer' ), $update->update->new_version );
1320
  echo '</strong></p></div>';
1331
  */
1332
  function greet() {
1333
  echo '<div class="narrow">';
1334
+ echo '<p>' . __( 'Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import the posts, pages, comments, custom fields, categories, and tags into this site.', 'wordpress-importer' ) . '</p>';
1335
+ echo '<p>' . __( 'Choose a WXR (.xml) file to upload, then click Upload file and import.', 'wordpress-importer' ) . '</p>';
1336
  wp_import_upload_form( 'admin.php?import=wordpress&amp;step=1' );
1337
  echo '</div>';
1338
  }
1346
  function is_valid_meta_key( $key ) {
1347
  // skip attachment metadata since we'll regenerate it from scratch
1348
  // skip _edit_lock as not relevant for import
1349
+ if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ), true ) ) {
1350
  return false;
1351
+ }
1352
  return $key;
1353
  }
1354
 
1393
 
1394
  // return the difference in length between two strings
1395
  function cmpr_strlen( $a, $b ) {
1396
+ return strlen( $b ) - strlen( $a );
1397
  }
1398
 
1399
  /**
compat.php CHANGED
@@ -37,33 +37,3 @@ if ( ! function_exists( 'addslashes_strings_only' ) ) {
37
  return is_string( $value ) ? addslashes( $value ) : $value;
38
  }
39
  }
40
-
41
- if ( ! function_exists( 'map_deep' ) ) {
42
- /**
43
- * Maps a function to all non-iterable elements of an array or an object.
44
- *
45
- * Compat for WordPress < 4.4.0.
46
- *
47
- * @since 0.7.0
48
- *
49
- * @param mixed $value The array, object, or scalar.
50
- * @param callable $callback The function to map onto $value.
51
- * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
52
- */
53
- function map_deep( $value, $callback ) {
54
- if ( is_array( $value ) ) {
55
- foreach ( $value as $index => $item ) {
56
- $value[ $index ] = map_deep( $item, $callback );
57
- }
58
- } elseif ( is_object( $value ) ) {
59
- $object_vars = get_object_vars( $value );
60
- foreach ( $object_vars as $property_name => $property_value ) {
61
- $value->$property_name = map_deep( $property_value, $callback );
62
- }
63
- } else {
64
- $value = call_user_func( $callback, $value );
65
- }
66
-
67
- return $value;
68
- }
69
- }
37
  return is_string( $value ) ? addslashes( $value ) : $value;
38
  }
39
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
parsers/class-wxr-parser-regex.php CHANGED
@@ -10,20 +10,22 @@
10
  * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
11
  */
12
  class WXR_Parser_Regex {
13
- var $authors = array();
14
- var $posts = array();
15
- var $categories = array();
16
- var $tags = array();
17
- var $terms = array();
18
- var $base_url = '';
19
- var $base_blog_url = '';
 
20
 
21
  function __construct() {
22
  $this->has_gzip = is_callable( 'gzopen' );
23
  }
24
 
25
  function parse( $file ) {
26
- $wxr_version = $in_multiline = false;
 
27
 
28
  $multiline_content = '';
29
 
@@ -37,10 +39,12 @@ class WXR_Parser_Regex {
37
  $fp = $this->fopen( $file, 'r' );
38
  if ( $fp ) {
39
  while ( ! $this->feof( $fp ) ) {
40
- $importline = rtrim( $this->fgets( $fp ) );
 
41
 
42
- if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) )
43
  $wxr_version = $version[1];
 
44
 
45
  if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
46
  preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
@@ -52,58 +56,61 @@ class WXR_Parser_Regex {
52
  preg_match( '|<wp:base_blog_url>(.*?)</wp:base_blog_url>|is', $importline, $blog_url );
53
  $this->base_blog_url = $blog_url[1];
54
  continue;
55
- } else {
56
  $this->base_blog_url = $this->base_url;
57
  }
58
 
59
  if ( false !== strpos( $importline, '<wp:author>' ) ) {
60
  preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
61
- $a = $this->process_author( $author[1] );
62
- $this->authors[$a['author_login']] = $a;
63
  continue;
64
  }
65
 
66
  foreach ( $multiline_tags as $tag => $handler ) {
67
  // Handle multi-line tags on a singular line
 
 
68
  if ( preg_match( '|<' . $tag . '>(.*?)</' . $tag . '>|is', $importline, $matches ) ) {
69
  $this->{$handler[0]}[] = call_user_func( $handler[1], $matches[1] );
70
 
71
- } elseif ( false !== ( $pos = strpos( $importline, "<$tag>" ) ) ) {
72
  // Take note of any content after the opening tag
73
  $multiline_content = trim( substr( $importline, $pos + strlen( $tag ) + 2 ) );
74
 
75
  // We don't want to have this line added to `$is_multiline` below.
76
- $importline = '';
77
- $in_multiline = $tag;
78
 
79
- } elseif ( false !== ( $pos = strpos( $importline, "</$tag>" ) ) ) {
80
- $in_multiline = false;
81
- $multiline_content .= trim( substr( $importline, 0, $pos ) );
82
 
83
  $this->{$handler[0]}[] = call_user_func( $handler[1], $multiline_content );
84
  }
85
  }
86
 
87
- if ( $in_multiline && $importline ) {
88
  $multiline_content .= $importline . "\n";
89
  }
90
  }
91
 
92
- $this->fclose($fp);
93
  }
94
 
95
- if ( ! $wxr_version )
96
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
 
97
 
98
  return array(
99
- 'authors' => $this->authors,
100
- 'posts' => $this->posts,
101
- 'categories' => $this->categories,
102
- 'tags' => $this->tags,
103
- 'terms' => $this->terms,
104
- 'base_url' => $this->base_url,
105
  'base_blog_url' => $this->base_blog_url,
106
- 'version' => $wxr_version
107
  );
108
  }
109
 
@@ -114,8 +121,9 @@ class WXR_Parser_Regex {
114
  if ( strpos( $return[1], ']]]]><![CDATA[>' ) !== false ) {
115
  preg_match_all( '|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches );
116
  $return = '';
117
- foreach( $matches[1] as $match )
118
  $return .= $match;
 
119
  } else {
120
  $return = preg_replace( '|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1] );
121
  }
@@ -130,10 +138,10 @@ class WXR_Parser_Regex {
130
 
131
  function process_category( $c ) {
132
  $term = array(
133
- 'term_id' => $this->get_tag( $c, 'wp:term_id' ),
134
- 'cat_name' => $this->get_tag( $c, 'wp:cat_name' ),
135
- 'category_nicename' => $this->get_tag( $c, 'wp:category_nicename' ),
136
- 'category_parent' => $this->get_tag( $c, 'wp:category_parent' ),
137
  'category_description' => $this->get_tag( $c, 'wp:category_description' ),
138
  );
139
 
@@ -147,9 +155,9 @@ class WXR_Parser_Regex {
147
 
148
  function process_tag( $t ) {
149
  $term = array(
150
- 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
151
- 'tag_name' => $this->get_tag( $t, 'wp:tag_name' ),
152
- 'tag_slug' => $this->get_tag( $t, 'wp:tag_slug' ),
153
  'tag_description' => $this->get_tag( $t, 'wp:tag_description' ),
154
  );
155
 
@@ -163,11 +171,11 @@ class WXR_Parser_Regex {
163
 
164
  function process_term( $t ) {
165
  $term = array(
166
- 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
167
- 'term_taxonomy' => $this->get_tag( $t, 'wp:term_taxonomy' ),
168
- 'slug' => $this->get_tag( $t, 'wp:term_slug' ),
169
- 'term_parent' => $this->get_tag( $t, 'wp:term_parent' ),
170
- 'term_name' => $this->get_tag( $t, 'wp:term_name' ),
171
  'term_description' => $this->get_tag( $t, 'wp:term_description' ),
172
  );
173
 
@@ -200,12 +208,12 @@ class WXR_Parser_Regex {
200
 
201
  function process_author( $a ) {
202
  return array(
203
- 'author_id' => $this->get_tag( $a, 'wp:author_id' ),
204
- 'author_login' => $this->get_tag( $a, 'wp:author_login' ),
205
- 'author_email' => $this->get_tag( $a, 'wp:author_email' ),
206
  'author_display_name' => $this->get_tag( $a, 'wp:author_display_name' ),
207
- 'author_first_name' => $this->get_tag( $a, 'wp:author_first_name' ),
208
- 'author_last_name' => $this->get_tag( $a, 'wp:author_last_name' ),
209
  );
210
  }
211
 
@@ -236,43 +244,61 @@ class WXR_Parser_Regex {
236
  $post_content = str_replace( '<br>', '<br />', $post_content );
237
  $post_content = str_replace( '<hr>', '<hr />', $post_content );
238
 
239
- $postdata = compact( 'post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt',
240
- 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent',
241
- 'menu_order', 'post_type', 'post_password', 'is_sticky'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  );
243
 
244
  $attachment_url = $this->get_tag( $post, 'wp:attachment_url' );
245
- if ( $attachment_url )
246
  $postdata['attachment_url'] = $attachment_url;
 
247
 
248
  preg_match_all( '|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER );
249
  foreach ( $terms as $t ) {
250
  $post_terms[] = array(
251
- 'slug' => $t[2],
252
  'domain' => $t[1],
253
- 'name' => str_replace( array( '<![CDATA[', ']]>' ), '', $t[3] ),
254
  );
255
  }
256
- if ( ! empty( $post_terms ) ) $postdata['terms'] = $post_terms;
 
 
257
 
258
  preg_match_all( '|<wp:comment>(.+?)</wp:comment>|is', $post, $comments );
259
  $comments = $comments[1];
260
  if ( $comments ) {
261
  foreach ( $comments as $comment ) {
262
  $post_comments[] = array(
263
- 'comment_id' => $this->get_tag( $comment, 'wp:comment_id' ),
264
- 'comment_author' => $this->get_tag( $comment, 'wp:comment_author' ),
265
  'comment_author_email' => $this->get_tag( $comment, 'wp:comment_author_email' ),
266
- 'comment_author_IP' => $this->get_tag( $comment, 'wp:comment_author_IP' ),
267
- 'comment_author_url' => $this->get_tag( $comment, 'wp:comment_author_url' ),
268
- 'comment_date' => $this->get_tag( $comment, 'wp:comment_date' ),
269
- 'comment_date_gmt' => $this->get_tag( $comment, 'wp:comment_date_gmt' ),
270
- 'comment_content' => $this->get_tag( $comment, 'wp:comment_content' ),
271
- 'comment_approved' => $this->get_tag( $comment, 'wp:comment_approved' ),
272
- 'comment_type' => $this->get_tag( $comment, 'wp:comment_type' ),
273
- 'comment_parent' => $this->get_tag( $comment, 'wp:comment_parent' ),
274
- 'comment_user_id' => $this->get_tag( $comment, 'wp:comment_user_id' ),
275
- 'commentmeta' => $this->process_meta( $comment, 'wp:commentmeta' ),
276
  );
277
  }
278
  }
@@ -293,26 +319,30 @@ class WXR_Parser_Regex {
293
  }
294
 
295
  function fopen( $filename, $mode = 'r' ) {
296
- if ( $this->has_gzip )
297
  return gzopen( $filename, $mode );
 
298
  return fopen( $filename, $mode );
299
  }
300
 
301
  function feof( $fp ) {
302
- if ( $this->has_gzip )
303
  return gzeof( $fp );
 
304
  return feof( $fp );
305
  }
306
 
307
  function fgets( $fp, $len = 8192 ) {
308
- if ( $this->has_gzip )
309
  return gzgets( $fp, $len );
 
310
  return fgets( $fp, $len );
311
  }
312
 
313
  function fclose( $fp ) {
314
- if ( $this->has_gzip )
315
  return gzclose( $fp );
 
316
  return fclose( $fp );
317
  }
318
  }
10
  * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
11
  */
12
  class WXR_Parser_Regex {
13
+ public $authors = array();
14
+ public $posts = array();
15
+ public $categories = array();
16
+ public $tags = array();
17
+ public $terms = array();
18
+ public $base_url = '';
19
+ public $base_blog_url = '';
20
+ public $has_gzip;
21
 
22
  function __construct() {
23
  $this->has_gzip = is_callable( 'gzopen' );
24
  }
25
 
26
  function parse( $file ) {
27
+ $wxr_version = false;
28
+ $in_multiline = false;
29
 
30
  $multiline_content = '';
31
 
39
  $fp = $this->fopen( $file, 'r' );
40
  if ( $fp ) {
41
  while ( ! $this->feof( $fp ) ) {
42
+ $is_tag_line = false;
43
+ $importline = rtrim( $this->fgets( $fp ) );
44
 
45
+ if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) ) {
46
  $wxr_version = $version[1];
47
+ }
48
 
49
  if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
50
  preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
56
  preg_match( '|<wp:base_blog_url>(.*?)</wp:base_blog_url>|is', $importline, $blog_url );
57
  $this->base_blog_url = $blog_url[1];
58
  continue;
59
+ } elseif ( empty( $this->base_blog_url ) ) {
60
  $this->base_blog_url = $this->base_url;
61
  }
62
 
63
  if ( false !== strpos( $importline, '<wp:author>' ) ) {
64
  preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
65
+ $a = $this->process_author( $author[1] );
66
+ $this->authors[ $a['author_login'] ] = $a;
67
  continue;
68
  }
69
 
70
  foreach ( $multiline_tags as $tag => $handler ) {
71
  // Handle multi-line tags on a singular line
72
+ $pos = strpos( $importline, "<$tag>" );
73
+ $pos_closing = strpos( $importline, "</$tag>" );
74
  if ( preg_match( '|<' . $tag . '>(.*?)</' . $tag . '>|is', $importline, $matches ) ) {
75
  $this->{$handler[0]}[] = call_user_func( $handler[1], $matches[1] );
76
 
77
+ } elseif ( false !== $pos ) {
78
  // Take note of any content after the opening tag
79
  $multiline_content = trim( substr( $importline, $pos + strlen( $tag ) + 2 ) );
80
 
81
  // We don't want to have this line added to `$is_multiline` below.
82
+ $in_multiline = $tag;
83
+ $is_tag_line = true;
84
 
85
+ } elseif ( false !== $pos_closing ) {
86
+ $in_multiline = false;
87
+ $multiline_content .= trim( substr( $importline, 0, $pos_closing ) );
88
 
89
  $this->{$handler[0]}[] = call_user_func( $handler[1], $multiline_content );
90
  }
91
  }
92
 
93
+ if ( $in_multiline && ! $is_tag_line ) {
94
  $multiline_content .= $importline . "\n";
95
  }
96
  }
97
 
98
+ $this->fclose( $fp );
99
  }
100
 
101
+ if ( ! $wxr_version ) {
102
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
103
+ }
104
 
105
  return array(
106
+ 'authors' => $this->authors,
107
+ 'posts' => $this->posts,
108
+ 'categories' => $this->categories,
109
+ 'tags' => $this->tags,
110
+ 'terms' => $this->terms,
111
+ 'base_url' => $this->base_url,
112
  'base_blog_url' => $this->base_blog_url,
113
+ 'version' => $wxr_version,
114
  );
115
  }
116
 
121
  if ( strpos( $return[1], ']]]]><![CDATA[>' ) !== false ) {
122
  preg_match_all( '|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches );
123
  $return = '';
124
+ foreach ( $matches[1] as $match ) {
125
  $return .= $match;
126
+ }
127
  } else {
128
  $return = preg_replace( '|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1] );
129
  }
138
 
139
  function process_category( $c ) {
140
  $term = array(
141
+ 'term_id' => $this->get_tag( $c, 'wp:term_id' ),
142
+ 'cat_name' => $this->get_tag( $c, 'wp:cat_name' ),
143
+ 'category_nicename' => $this->get_tag( $c, 'wp:category_nicename' ),
144
+ 'category_parent' => $this->get_tag( $c, 'wp:category_parent' ),
145
  'category_description' => $this->get_tag( $c, 'wp:category_description' ),
146
  );
147
 
155
 
156
  function process_tag( $t ) {
157
  $term = array(
158
+ 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
159
+ 'tag_name' => $this->get_tag( $t, 'wp:tag_name' ),
160
+ 'tag_slug' => $this->get_tag( $t, 'wp:tag_slug' ),
161
  'tag_description' => $this->get_tag( $t, 'wp:tag_description' ),
162
  );
163
 
171
 
172
  function process_term( $t ) {
173
  $term = array(
174
+ 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
175
+ 'term_taxonomy' => $this->get_tag( $t, 'wp:term_taxonomy' ),
176
+ 'slug' => $this->get_tag( $t, 'wp:term_slug' ),
177
+ 'term_parent' => $this->get_tag( $t, 'wp:term_parent' ),
178
+ 'term_name' => $this->get_tag( $t, 'wp:term_name' ),
179
  'term_description' => $this->get_tag( $t, 'wp:term_description' ),
180
  );
181
 
208
 
209
  function process_author( $a ) {
210
  return array(
211
+ 'author_id' => $this->get_tag( $a, 'wp:author_id' ),
212
+ 'author_login' => $this->get_tag( $a, 'wp:author_login' ),
213
+ 'author_email' => $this->get_tag( $a, 'wp:author_email' ),
214
  'author_display_name' => $this->get_tag( $a, 'wp:author_display_name' ),
215
+ 'author_first_name' => $this->get_tag( $a, 'wp:author_first_name' ),
216
+ 'author_last_name' => $this->get_tag( $a, 'wp:author_last_name' ),
217
  );
218
  }
219
 
244
  $post_content = str_replace( '<br>', '<br />', $post_content );
245
  $post_content = str_replace( '<hr>', '<hr />', $post_content );
246
 
247
+ $postdata = compact(
248
+ 'post_id',
249
+ 'post_author',
250
+ 'post_date',
251
+ 'post_date_gmt',
252
+ 'post_content',
253
+ 'post_excerpt',
254
+ 'post_title',
255
+ 'status',
256
+ 'post_name',
257
+ 'comment_status',
258
+ 'ping_status',
259
+ 'guid',
260
+ 'post_parent',
261
+ 'menu_order',
262
+ 'post_type',
263
+ 'post_password',
264
+ 'is_sticky'
265
  );
266
 
267
  $attachment_url = $this->get_tag( $post, 'wp:attachment_url' );
268
+ if ( $attachment_url ) {
269
  $postdata['attachment_url'] = $attachment_url;
270
+ }
271
 
272
  preg_match_all( '|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER );
273
  foreach ( $terms as $t ) {
274
  $post_terms[] = array(
275
+ 'slug' => $t[2],
276
  'domain' => $t[1],
277
+ 'name' => str_replace( array( '<![CDATA[', ']]>' ), '', $t[3] ),
278
  );
279
  }
280
+ if ( ! empty( $post_terms ) ) {
281
+ $postdata['terms'] = $post_terms;
282
+ }
283
 
284
  preg_match_all( '|<wp:comment>(.+?)</wp:comment>|is', $post, $comments );
285
  $comments = $comments[1];
286
  if ( $comments ) {
287
  foreach ( $comments as $comment ) {
288
  $post_comments[] = array(
289
+ 'comment_id' => $this->get_tag( $comment, 'wp:comment_id' ),
290
+ 'comment_author' => $this->get_tag( $comment, 'wp:comment_author' ),
291
  'comment_author_email' => $this->get_tag( $comment, 'wp:comment_author_email' ),
292
+ 'comment_author_IP' => $this->get_tag( $comment, 'wp:comment_author_IP' ),
293
+ 'comment_author_url' => $this->get_tag( $comment, 'wp:comment_author_url' ),
294
+ 'comment_date' => $this->get_tag( $comment, 'wp:comment_date' ),
295
+ 'comment_date_gmt' => $this->get_tag( $comment, 'wp:comment_date_gmt' ),
296
+ 'comment_content' => $this->get_tag( $comment, 'wp:comment_content' ),
297
+ 'comment_approved' => $this->get_tag( $comment, 'wp:comment_approved' ),
298
+ 'comment_type' => $this->get_tag( $comment, 'wp:comment_type' ),
299
+ 'comment_parent' => $this->get_tag( $comment, 'wp:comment_parent' ),
300
+ 'comment_user_id' => $this->get_tag( $comment, 'wp:comment_user_id' ),
301
+ 'commentmeta' => $this->process_meta( $comment, 'wp:commentmeta' ),
302
  );
303
  }
304
  }
319
  }
320
 
321
  function fopen( $filename, $mode = 'r' ) {
322
+ if ( $this->has_gzip ) {
323
  return gzopen( $filename, $mode );
324
+ }
325
  return fopen( $filename, $mode );
326
  }
327
 
328
  function feof( $fp ) {
329
+ if ( $this->has_gzip ) {
330
  return gzeof( $fp );
331
+ }
332
  return feof( $fp );
333
  }
334
 
335
  function fgets( $fp, $len = 8192 ) {
336
+ if ( $this->has_gzip ) {
337
  return gzgets( $fp, $len );
338
+ }
339
  return fgets( $fp, $len );
340
  }
341
 
342
  function fclose( $fp ) {
343
+ if ( $this->has_gzip ) {
344
  return gzclose( $fp );
345
+ }
346
  return fclose( $fp );
347
  }
348
  }
parsers/class-wxr-parser-simplexml.php CHANGED
@@ -11,13 +11,17 @@
11
  */
12
  class WXR_Parser_SimpleXML {
13
  function parse( $file ) {
14
- $authors = $posts = $categories = $tags = $terms = array();
 
 
 
 
15
 
16
- $internal_errors = libxml_use_internal_errors(true);
17
 
18
- $dom = new DOMDocument;
19
  $old_value = null;
20
- if ( function_exists( 'libxml_disable_entity_loader' ) ) {
21
  $old_value = libxml_disable_entity_loader( true );
22
  }
23
  $success = $dom->loadXML( file_get_contents( $file ) );
@@ -33,23 +37,25 @@ class WXR_Parser_SimpleXML {
33
  unset( $dom );
34
 
35
  // halt if loading produces an error
36
- if ( ! $xml )
37
  return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() );
 
38
 
39
- $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
40
- if ( ! $wxr_version )
41
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
 
42
 
43
  $wxr_version = (string) trim( $wxr_version[0] );
44
  // confirm that we are dealing with the correct file format
45
- if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) )
46
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
 
47
 
48
- $base_url = $xml->xpath('/rss/channel/wp:base_site_url');
49
  $base_url = (string) trim( isset( $base_url[0] ) ? $base_url[0] : '' );
50
 
51
-
52
- $base_blog_url = $xml->xpath('/rss/channel/wp:base_blog_url');
53
  if ( $base_blog_url ) {
54
  $base_blog_url = (string) trim( $base_blog_url[0] );
55
  } else {
@@ -57,80 +63,82 @@ class WXR_Parser_SimpleXML {
57
  }
58
 
59
  $namespaces = $xml->getDocNamespaces();
60
- if ( ! isset( $namespaces['wp'] ) )
61
  $namespaces['wp'] = 'http://wordpress.org/export/1.1/';
62
- if ( ! isset( $namespaces['excerpt'] ) )
 
63
  $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
 
64
 
65
  // grab authors
66
- foreach ( $xml->xpath('/rss/channel/wp:author') as $author_arr ) {
67
- $a = $author_arr->children( $namespaces['wp'] );
68
- $login = (string) $a->author_login;
69
- $authors[$login] = array(
70
- 'author_id' => (int) $a->author_id,
71
- 'author_login' => $login,
72
- 'author_email' => (string) $a->author_email,
73
  'author_display_name' => (string) $a->author_display_name,
74
- 'author_first_name' => (string) $a->author_first_name,
75
- 'author_last_name' => (string) $a->author_last_name
76
  );
77
  }
78
 
79
  // grab cats, tags and terms
80
- foreach ( $xml->xpath('/rss/channel/wp:category') as $term_arr ) {
81
- $t = $term_arr->children( $namespaces['wp'] );
82
  $category = array(
83
- 'term_id' => (int) $t->term_id,
84
- 'category_nicename' => (string) $t->category_nicename,
85
- 'category_parent' => (string) $t->category_parent,
86
- 'cat_name' => (string) $t->cat_name,
87
- 'category_description' => (string) $t->category_description
88
  );
89
 
90
  foreach ( $t->termmeta as $meta ) {
91
  $category['termmeta'][] = array(
92
- 'key' => (string) $meta->meta_key,
93
- 'value' => (string) $meta->meta_value
94
  );
95
  }
96
 
97
  $categories[] = $category;
98
  }
99
 
100
- foreach ( $xml->xpath('/rss/channel/wp:tag') as $term_arr ) {
101
- $t = $term_arr->children( $namespaces['wp'] );
102
  $tag = array(
103
- 'term_id' => (int) $t->term_id,
104
- 'tag_slug' => (string) $t->tag_slug,
105
- 'tag_name' => (string) $t->tag_name,
106
- 'tag_description' => (string) $t->tag_description
107
  );
108
 
109
  foreach ( $t->termmeta as $meta ) {
110
  $tag['termmeta'][] = array(
111
- 'key' => (string) $meta->meta_key,
112
- 'value' => (string) $meta->meta_value
113
  );
114
  }
115
 
116
  $tags[] = $tag;
117
  }
118
 
119
- foreach ( $xml->xpath('/rss/channel/wp:term') as $term_arr ) {
120
- $t = $term_arr->children( $namespaces['wp'] );
121
  $term = array(
122
- 'term_id' => (int) $t->term_id,
123
- 'term_taxonomy' => (string) $t->term_taxonomy,
124
- 'slug' => (string) $t->term_slug,
125
- 'term_parent' => (string) $t->term_parent,
126
- 'term_name' => (string) $t->term_name,
127
- 'term_description' => (string) $t->term_description
128
  );
129
 
130
  foreach ( $t->termmeta as $meta ) {
131
  $term['termmeta'][] = array(
132
- 'key' => (string) $meta->meta_key,
133
- 'value' => (string) $meta->meta_value
134
  );
135
  }
136
 
@@ -141,48 +149,50 @@ class WXR_Parser_SimpleXML {
141
  foreach ( $xml->channel->item as $item ) {
142
  $post = array(
143
  'post_title' => (string) $item->title,
144
- 'guid' => (string) $item->guid,
145
  );
146
 
147
- $dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
148
  $post['post_author'] = (string) $dc->creator;
149
 
150
- $content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
151
- $excerpt = $item->children( $namespaces['excerpt'] );
152
  $post['post_content'] = (string) $content->encoded;
153
  $post['post_excerpt'] = (string) $excerpt->encoded;
154
 
155
- $wp = $item->children( $namespaces['wp'] );
156
- $post['post_id'] = (int) $wp->post_id;
157
- $post['post_date'] = (string) $wp->post_date;
158
- $post['post_date_gmt'] = (string) $wp->post_date_gmt;
159
  $post['comment_status'] = (string) $wp->comment_status;
160
- $post['ping_status'] = (string) $wp->ping_status;
161
- $post['post_name'] = (string) $wp->post_name;
162
- $post['status'] = (string) $wp->status;
163
- $post['post_parent'] = (int) $wp->post_parent;
164
- $post['menu_order'] = (int) $wp->menu_order;
165
- $post['post_type'] = (string) $wp->post_type;
166
- $post['post_password'] = (string) $wp->post_password;
167
- $post['is_sticky'] = (int) $wp->is_sticky;
168
-
169
- if ( isset($wp->attachment_url) )
170
  $post['attachment_url'] = (string) $wp->attachment_url;
 
171
 
172
  foreach ( $item->category as $c ) {
173
  $att = $c->attributes();
174
- if ( isset( $att['nicename'] ) )
175
  $post['terms'][] = array(
176
- 'name' => (string) $c,
177
- 'slug' => (string) $att['nicename'],
178
- 'domain' => (string) $att['domain']
179
  );
 
180
  }
181
 
182
  foreach ( $wp->postmeta as $meta ) {
183
  $post['postmeta'][] = array(
184
- 'key' => (string) $meta->meta_key,
185
- 'value' => (string) $meta->meta_value
186
  );
187
  }
188
 
@@ -191,26 +201,26 @@ class WXR_Parser_SimpleXML {
191
  if ( isset( $comment->commentmeta ) ) {
192
  foreach ( $comment->commentmeta as $m ) {
193
  $meta[] = array(
194
- 'key' => (string) $m->meta_key,
195
- 'value' => (string) $m->meta_value
196
  );
197
  }
198
  }
199
 
200
  $post['comments'][] = array(
201
- 'comment_id' => (int) $comment->comment_id,
202
- 'comment_author' => (string) $comment->comment_author,
203
  'comment_author_email' => (string) $comment->comment_author_email,
204
- 'comment_author_IP' => (string) $comment->comment_author_IP,
205
- 'comment_author_url' => (string) $comment->comment_author_url,
206
- 'comment_date' => (string) $comment->comment_date,
207
- 'comment_date_gmt' => (string) $comment->comment_date_gmt,
208
- 'comment_content' => (string) $comment->comment_content,
209
- 'comment_approved' => (string) $comment->comment_approved,
210
- 'comment_type' => (string) $comment->comment_type,
211
- 'comment_parent' => (string) $comment->comment_parent,
212
- 'comment_user_id' => (int) $comment->comment_user_id,
213
- 'commentmeta' => $meta,
214
  );
215
  }
216
 
@@ -218,14 +228,14 @@ class WXR_Parser_SimpleXML {
218
  }
219
 
220
  return array(
221
- 'authors' => $authors,
222
- 'posts' => $posts,
223
- 'categories' => $categories,
224
- 'tags' => $tags,
225
- 'terms' => $terms,
226
- 'base_url' => $base_url,
227
  'base_blog_url' => $base_blog_url,
228
- 'version' => $wxr_version
229
  );
230
  }
231
  }
11
  */
12
  class WXR_Parser_SimpleXML {
13
  function parse( $file ) {
14
+ $authors = array();
15
+ $posts = array();
16
+ $categories = array();
17
+ $tags = array();
18
+ $terms = array();
19
 
20
+ $internal_errors = libxml_use_internal_errors( true );
21
 
22
+ $dom = new DOMDocument;
23
  $old_value = null;
24
+ if ( function_exists( 'libxml_disable_entity_loader' ) && PHP_VERSION_ID < 80000 ) {
25
  $old_value = libxml_disable_entity_loader( true );
26
  }
27
  $success = $dom->loadXML( file_get_contents( $file ) );
37
  unset( $dom );
38
 
39
  // halt if loading produces an error
40
+ if ( ! $xml ) {
41
  return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'wordpress-importer' ), libxml_get_errors() );
42
+ }
43
 
44
+ $wxr_version = $xml->xpath( '/rss/channel/wp:wxr_version' );
45
+ if ( ! $wxr_version ) {
46
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
47
+ }
48
 
49
  $wxr_version = (string) trim( $wxr_version[0] );
50
  // confirm that we are dealing with the correct file format
51
+ if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) ) {
52
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
53
+ }
54
 
55
+ $base_url = $xml->xpath( '/rss/channel/wp:base_site_url' );
56
  $base_url = (string) trim( isset( $base_url[0] ) ? $base_url[0] : '' );
57
 
58
+ $base_blog_url = $xml->xpath( '/rss/channel/wp:base_blog_url' );
 
59
  if ( $base_blog_url ) {
60
  $base_blog_url = (string) trim( $base_blog_url[0] );
61
  } else {
63
  }
64
 
65
  $namespaces = $xml->getDocNamespaces();
66
+ if ( ! isset( $namespaces['wp'] ) ) {
67
  $namespaces['wp'] = 'http://wordpress.org/export/1.1/';
68
+ }
69
+ if ( ! isset( $namespaces['excerpt'] ) ) {
70
  $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
71
+ }
72
 
73
  // grab authors
74
+ foreach ( $xml->xpath( '/rss/channel/wp:author' ) as $author_arr ) {
75
+ $a = $author_arr->children( $namespaces['wp'] );
76
+ $login = (string) $a->author_login;
77
+ $authors[ $login ] = array(
78
+ 'author_id' => (int) $a->author_id,
79
+ 'author_login' => $login,
80
+ 'author_email' => (string) $a->author_email,
81
  'author_display_name' => (string) $a->author_display_name,
82
+ 'author_first_name' => (string) $a->author_first_name,
83
+ 'author_last_name' => (string) $a->author_last_name,
84
  );
85
  }
86
 
87
  // grab cats, tags and terms
88
+ foreach ( $xml->xpath( '/rss/channel/wp:category' ) as $term_arr ) {
89
+ $t = $term_arr->children( $namespaces['wp'] );
90
  $category = array(
91
+ 'term_id' => (int) $t->term_id,
92
+ 'category_nicename' => (string) $t->category_nicename,
93
+ 'category_parent' => (string) $t->category_parent,
94
+ 'cat_name' => (string) $t->cat_name,
95
+ 'category_description' => (string) $t->category_description,
96
  );
97
 
98
  foreach ( $t->termmeta as $meta ) {
99
  $category['termmeta'][] = array(
100
+ 'key' => (string) $meta->meta_key,
101
+ 'value' => (string) $meta->meta_value,
102
  );
103
  }
104
 
105
  $categories[] = $category;
106
  }
107
 
108
+ foreach ( $xml->xpath( '/rss/channel/wp:tag' ) as $term_arr ) {
109
+ $t = $term_arr->children( $namespaces['wp'] );
110
  $tag = array(
111
+ 'term_id' => (int) $t->term_id,
112
+ 'tag_slug' => (string) $t->tag_slug,
113
+ 'tag_name' => (string) $t->tag_name,
114
+ 'tag_description' => (string) $t->tag_description,
115
  );
116
 
117
  foreach ( $t->termmeta as $meta ) {
118
  $tag['termmeta'][] = array(
119
+ 'key' => (string) $meta->meta_key,
120
+ 'value' => (string) $meta->meta_value,
121
  );
122
  }
123
 
124
  $tags[] = $tag;
125
  }
126
 
127
+ foreach ( $xml->xpath( '/rss/channel/wp:term' ) as $term_arr ) {
128
+ $t = $term_arr->children( $namespaces['wp'] );
129
  $term = array(
130
+ 'term_id' => (int) $t->term_id,
131
+ 'term_taxonomy' => (string) $t->term_taxonomy,
132
+ 'slug' => (string) $t->term_slug,
133
+ 'term_parent' => (string) $t->term_parent,
134
+ 'term_name' => (string) $t->term_name,
135
+ 'term_description' => (string) $t->term_description,
136
  );
137
 
138
  foreach ( $t->termmeta as $meta ) {
139
  $term['termmeta'][] = array(
140
+ 'key' => (string) $meta->meta_key,
141
+ 'value' => (string) $meta->meta_value,
142
  );
143
  }
144
 
149
  foreach ( $xml->channel->item as $item ) {
150
  $post = array(
151
  'post_title' => (string) $item->title,
152
+ 'guid' => (string) $item->guid,
153
  );
154
 
155
+ $dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
156
  $post['post_author'] = (string) $dc->creator;
157
 
158
+ $content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
159
+ $excerpt = $item->children( $namespaces['excerpt'] );
160
  $post['post_content'] = (string) $content->encoded;
161
  $post['post_excerpt'] = (string) $excerpt->encoded;
162
 
163
+ $wp = $item->children( $namespaces['wp'] );
164
+ $post['post_id'] = (int) $wp->post_id;
165
+ $post['post_date'] = (string) $wp->post_date;
166
+ $post['post_date_gmt'] = (string) $wp->post_date_gmt;
167
  $post['comment_status'] = (string) $wp->comment_status;
168
+ $post['ping_status'] = (string) $wp->ping_status;
169
+ $post['post_name'] = (string) $wp->post_name;
170
+ $post['status'] = (string) $wp->status;
171
+ $post['post_parent'] = (int) $wp->post_parent;
172
+ $post['menu_order'] = (int) $wp->menu_order;
173
+ $post['post_type'] = (string) $wp->post_type;
174
+ $post['post_password'] = (string) $wp->post_password;
175
+ $post['is_sticky'] = (int) $wp->is_sticky;
176
+
177
+ if ( isset( $wp->attachment_url ) ) {
178
  $post['attachment_url'] = (string) $wp->attachment_url;
179
+ }
180
 
181
  foreach ( $item->category as $c ) {
182
  $att = $c->attributes();
183
+ if ( isset( $att['nicename'] ) ) {
184
  $post['terms'][] = array(
185
+ 'name' => (string) $c,
186
+ 'slug' => (string) $att['nicename'],
187
+ 'domain' => (string) $att['domain'],
188
  );
189
+ }
190
  }
191
 
192
  foreach ( $wp->postmeta as $meta ) {
193
  $post['postmeta'][] = array(
194
+ 'key' => (string) $meta->meta_key,
195
+ 'value' => (string) $meta->meta_value,
196
  );
197
  }
198
 
201
  if ( isset( $comment->commentmeta ) ) {
202
  foreach ( $comment->commentmeta as $m ) {
203
  $meta[] = array(
204
+ 'key' => (string) $m->meta_key,
205
+ 'value' => (string) $m->meta_value,
206
  );
207
  }
208
  }
209
 
210
  $post['comments'][] = array(
211
+ 'comment_id' => (int) $comment->comment_id,
212
+ 'comment_author' => (string) $comment->comment_author,
213
  'comment_author_email' => (string) $comment->comment_author_email,
214
+ 'comment_author_IP' => (string) $comment->comment_author_IP,
215
+ 'comment_author_url' => (string) $comment->comment_author_url,
216
+ 'comment_date' => (string) $comment->comment_date,
217
+ 'comment_date_gmt' => (string) $comment->comment_date_gmt,
218
+ 'comment_content' => (string) $comment->comment_content,
219
+ 'comment_approved' => (string) $comment->comment_approved,
220
+ 'comment_type' => (string) $comment->comment_type,
221
+ 'comment_parent' => (string) $comment->comment_parent,
222
+ 'comment_user_id' => (int) $comment->comment_user_id,
223
+ 'commentmeta' => $meta,
224
  );
225
  }
226
 
228
  }
229
 
230
  return array(
231
+ 'authors' => $authors,
232
+ 'posts' => $posts,
233
+ 'categories' => $categories,
234
+ 'tags' => $tags,
235
+ 'terms' => $terms,
236
+ 'base_url' => $base_url,
237
  'base_blog_url' => $base_blog_url,
238
+ 'version' => $wxr_version,
239
  );
240
  }
241
  }
parsers/class-wxr-parser-xml.php CHANGED
@@ -10,23 +10,82 @@
10
  * WXR Parser that makes use of the XML Parser PHP extension.
11
  */
12
  class WXR_Parser_XML {
13
- var $wp_tags = array(
14
- 'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url',
15
- 'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password',
16
- 'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description',
17
- 'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent',
18
- 'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name',
19
- 'wp:author_first_name', 'wp:author_last_name',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  );
21
- var $wp_sub_tags = array(
22
- 'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url',
23
- 'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content',
24
- 'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id',
 
 
 
 
 
 
 
 
 
25
  );
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  function parse( $file ) {
28
- $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false;
29
- $this->authors = $this->posts = $this->term = $this->category = $this->tag = array();
 
 
 
 
 
 
 
 
 
 
30
 
31
  $xml = xml_parser_create( 'UTF-8' );
32
  xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
@@ -36,63 +95,89 @@ class WXR_Parser_XML {
36
  xml_set_element_handler( $xml, 'tag_open', 'tag_close' );
37
 
38
  if ( ! xml_parse( $xml, file_get_contents( $file ), true ) ) {
39
- $current_line = xml_get_current_line_number( $xml );
40
  $current_column = xml_get_current_column_number( $xml );
41
- $error_code = xml_get_error_code( $xml );
42
- $error_string = xml_error_string( $error_code );
43
  return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array( $current_line, $current_column, $error_string ) );
44
  }
45
  xml_parser_free( $xml );
46
 
47
- if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) )
48
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
 
49
 
50
  return array(
51
- 'authors' => $this->authors,
52
- 'posts' => $this->posts,
53
- 'categories' => $this->category,
54
- 'tags' => $this->tag,
55
- 'terms' => $this->term,
56
- 'base_url' => $this->base_url,
57
  'base_blog_url' => $this->base_blog_url,
58
- 'version' => $this->wxr_version
59
  );
60
  }
61
 
62
  function tag_open( $parse, $tag, $attr ) {
63
- if ( in_array( $tag, $this->wp_tags ) ) {
64
  $this->in_tag = substr( $tag, 3 );
65
  return;
66
  }
67
 
68
- if ( in_array( $tag, $this->wp_sub_tags ) ) {
69
  $this->in_sub_tag = substr( $tag, 3 );
70
  return;
71
  }
72
 
73
  switch ( $tag ) {
74
  case 'category':
75
- if ( isset($attr['domain'], $attr['nicename']) ) {
 
 
 
 
76
  $this->sub_data['domain'] = $attr['domain'];
77
- $this->sub_data['slug'] = $attr['nicename'];
 
 
 
 
 
 
 
 
78
  }
79
  break;
80
- case 'item': $this->in_post = true;
81
- case 'title': if ( $this->in_post ) $this->in_tag = 'post_title'; break;
82
- case 'guid': $this->in_tag = 'guid'; break;
83
- case 'dc:creator': $this->in_tag = 'post_author'; break;
84
- case 'content:encoded': $this->in_tag = 'post_content'; break;
85
- case 'excerpt:encoded': $this->in_tag = 'post_excerpt'; break;
 
 
 
 
 
 
86
 
87
- case 'wp:term_slug': $this->in_tag = 'slug'; break;
88
- case 'wp:meta_key': $this->in_sub_tag = 'key'; break;
89
- case 'wp:meta_value': $this->in_sub_tag = 'value'; break;
 
 
 
 
 
 
90
  }
91
  }
92
 
93
  function cdata( $parser, $cdata ) {
94
- if ( ! trim( $cdata ) )
95
  return;
 
96
 
97
  if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
98
  $this->cdata .= $cdata;
@@ -105,31 +190,33 @@ class WXR_Parser_XML {
105
  switch ( $tag ) {
106
  case 'wp:comment':
107
  unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data
108
- if ( ! empty( $this->sub_data ) )
109
  $this->data['comments'][] = $this->sub_data;
 
110
  $this->sub_data = false;
111
  break;
112
  case 'wp:commentmeta':
113
  $this->sub_data['commentmeta'][] = array(
114
- 'key' => $this->sub_data['key'],
115
- 'value' => $this->sub_data['value']
116
  );
117
  break;
118
  case 'category':
119
  if ( ! empty( $this->sub_data ) ) {
120
  $this->sub_data['name'] = $this->cdata;
121
- $this->data['terms'][] = $this->sub_data;
122
  }
123
  $this->sub_data = false;
124
  break;
125
  case 'wp:postmeta':
126
- if ( ! empty( $this->sub_data ) )
127
  $this->data['postmeta'][] = $this->sub_data;
 
128
  $this->sub_data = false;
129
  break;
130
  case 'item':
131
  $this->posts[] = $this->data;
132
- $this->data = false;
133
  break;
134
  case 'wp:category':
135
  case 'wp:tag':
@@ -145,8 +232,9 @@ class WXR_Parser_XML {
145
  $this->sub_data = false;
146
  break;
147
  case 'wp:author':
148
- if ( ! empty($this->data['author_login']) )
149
- $this->authors[$this->data['author_login']] = $this->data;
 
150
  $this->data = false;
151
  break;
152
  case 'wp:base_site_url':
@@ -164,11 +252,19 @@ class WXR_Parser_XML {
164
 
165
  default:
166
  if ( $this->in_sub_tag ) {
167
- $this->sub_data[$this->in_sub_tag] = ! empty( $this->cdata ) ? $this->cdata : '';
168
- $this->in_sub_tag = false;
169
- } else if ( $this->in_tag ) {
170
- $this->data[$this->in_tag] = ! empty( $this->cdata ) ? $this->cdata : '';
171
- $this->in_tag = false;
 
 
 
 
 
 
 
 
172
  }
173
  }
174
 
10
  * WXR Parser that makes use of the XML Parser PHP extension.
11
  */
12
  class WXR_Parser_XML {
13
+ public $wp_tags = array(
14
+ 'wp:post_id',
15
+ 'wp:post_date',
16
+ 'wp:post_date_gmt',
17
+ 'wp:comment_status',
18
+ 'wp:ping_status',
19
+ 'wp:attachment_url',
20
+ 'wp:status',
21
+ 'wp:post_name',
22
+ 'wp:post_parent',
23
+ 'wp:menu_order',
24
+ 'wp:post_type',
25
+ 'wp:post_password',
26
+ 'wp:is_sticky',
27
+ 'wp:term_id',
28
+ 'wp:category_nicename',
29
+ 'wp:category_parent',
30
+ 'wp:cat_name',
31
+ 'wp:category_description',
32
+ 'wp:tag_slug',
33
+ 'wp:tag_name',
34
+ 'wp:tag_description',
35
+ 'wp:term_taxonomy',
36
+ 'wp:term_parent',
37
+ 'wp:term_name',
38
+ 'wp:term_description',
39
+ 'wp:author_id',
40
+ 'wp:author_login',
41
+ 'wp:author_email',
42
+ 'wp:author_display_name',
43
+ 'wp:author_first_name',
44
+ 'wp:author_last_name',
45
  );
46
+ public $wp_sub_tags = array(
47
+ 'wp:comment_id',
48
+ 'wp:comment_author',
49
+ 'wp:comment_author_email',
50
+ 'wp:comment_author_url',
51
+ 'wp:comment_author_IP',
52
+ 'wp:comment_date',
53
+ 'wp:comment_date_gmt',
54
+ 'wp:comment_content',
55
+ 'wp:comment_approved',
56
+ 'wp:comment_type',
57
+ 'wp:comment_parent',
58
+ 'wp:comment_user_id',
59
  );
60
 
61
+ public $wxr_version;
62
+ public $in_post;
63
+ public $cdata;
64
+ public $data;
65
+ public $sub_data;
66
+ public $in_tag;
67
+ public $in_sub_tag;
68
+ public $authors;
69
+ public $posts;
70
+ public $term;
71
+ public $category;
72
+ public $tag;
73
+ public $base_url;
74
+ public $base_blog_url;
75
+
76
  function parse( $file ) {
77
+ $this->wxr_version = false;
78
+ $this->in_post = false;
79
+ $this->cdata = false;
80
+ $this->data = false;
81
+ $this->sub_data = false;
82
+ $this->in_tag = false;
83
+ $this->in_sub_tag = false;
84
+ $this->authors = array();
85
+ $this->posts = array();
86
+ $this->term = array();
87
+ $this->category = array();
88
+ $this->tag = array();
89
 
90
  $xml = xml_parser_create( 'UTF-8' );
91
  xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
95
  xml_set_element_handler( $xml, 'tag_open', 'tag_close' );
96
 
97
  if ( ! xml_parse( $xml, file_get_contents( $file ), true ) ) {
98
+ $current_line = xml_get_current_line_number( $xml );
99
  $current_column = xml_get_current_column_number( $xml );
100
+ $error_code = xml_get_error_code( $xml );
101
+ $error_string = xml_error_string( $error_code );
102
  return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array( $current_line, $current_column, $error_string ) );
103
  }
104
  xml_parser_free( $xml );
105
 
106
+ if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) ) {
107
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer' ) );
108
+ }
109
 
110
  return array(
111
+ 'authors' => $this->authors,
112
+ 'posts' => $this->posts,
113
+ 'categories' => $this->category,
114
+ 'tags' => $this->tag,
115
+ 'terms' => $this->term,
116
+ 'base_url' => $this->base_url,
117
  'base_blog_url' => $this->base_blog_url,
118
+ 'version' => $this->wxr_version,
119
  );
120
  }
121
 
122
  function tag_open( $parse, $tag, $attr ) {
123
+ if ( in_array( $tag, $this->wp_tags, true ) ) {
124
  $this->in_tag = substr( $tag, 3 );
125
  return;
126
  }
127
 
128
+ if ( in_array( $tag, $this->wp_sub_tags, true ) ) {
129
  $this->in_sub_tag = substr( $tag, 3 );
130
  return;
131
  }
132
 
133
  switch ( $tag ) {
134
  case 'category':
135
+ if ( isset( $attr['domain'], $attr['nicename'] ) ) {
136
+ if ( false === $this->sub_data ) {
137
+ $this->sub_data = array();
138
+ }
139
+
140
  $this->sub_data['domain'] = $attr['domain'];
141
+ $this->sub_data['slug'] = $attr['nicename'];
142
+ }
143
+ break;
144
+ case 'item':
145
+ $this->in_post = true;
146
+ break;
147
+ case 'title':
148
+ if ( $this->in_post ) {
149
+ $this->in_tag = 'post_title';
150
  }
151
  break;
152
+ case 'guid':
153
+ $this->in_tag = 'guid';
154
+ break;
155
+ case 'dc:creator':
156
+ $this->in_tag = 'post_author';
157
+ break;
158
+ case 'content:encoded':
159
+ $this->in_tag = 'post_content';
160
+ break;
161
+ case 'excerpt:encoded':
162
+ $this->in_tag = 'post_excerpt';
163
+ break;
164
 
165
+ case 'wp:term_slug':
166
+ $this->in_tag = 'slug';
167
+ break;
168
+ case 'wp:meta_key':
169
+ $this->in_sub_tag = 'key';
170
+ break;
171
+ case 'wp:meta_value':
172
+ $this->in_sub_tag = 'value';
173
+ break;
174
  }
175
  }
176
 
177
  function cdata( $parser, $cdata ) {
178
+ if ( ! trim( $cdata ) ) {
179
  return;
180
+ }
181
 
182
  if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
183
  $this->cdata .= $cdata;
190
  switch ( $tag ) {
191
  case 'wp:comment':
192
  unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data
193
+ if ( ! empty( $this->sub_data ) ) {
194
  $this->data['comments'][] = $this->sub_data;
195
+ }
196
  $this->sub_data = false;
197
  break;
198
  case 'wp:commentmeta':
199
  $this->sub_data['commentmeta'][] = array(
200
+ 'key' => $this->sub_data['key'],
201
+ 'value' => $this->sub_data['value'],
202
  );
203
  break;
204
  case 'category':
205
  if ( ! empty( $this->sub_data ) ) {
206
  $this->sub_data['name'] = $this->cdata;
207
+ $this->data['terms'][] = $this->sub_data;
208
  }
209
  $this->sub_data = false;
210
  break;
211
  case 'wp:postmeta':
212
+ if ( ! empty( $this->sub_data ) ) {
213
  $this->data['postmeta'][] = $this->sub_data;
214
+ }
215
  $this->sub_data = false;
216
  break;
217
  case 'item':
218
  $this->posts[] = $this->data;
219
+ $this->data = false;
220
  break;
221
  case 'wp:category':
222
  case 'wp:tag':
232
  $this->sub_data = false;
233
  break;
234
  case 'wp:author':
235
+ if ( ! empty( $this->data['author_login'] ) ) {
236
+ $this->authors[ $this->data['author_login'] ] = $this->data;
237
+ }
238
  $this->data = false;
239
  break;
240
  case 'wp:base_site_url':
252
 
253
  default:
254
  if ( $this->in_sub_tag ) {
255
+ if ( false === $this->sub_data ) {
256
+ $this->sub_data = array();
257
+ }
258
+
259
+ $this->sub_data[ $this->in_sub_tag ] = ! empty( $this->cdata ) ? $this->cdata : '';
260
+ $this->in_sub_tag = false;
261
+ } elseif ( $this->in_tag ) {
262
+ if ( false === $this->data ) {
263
+ $this->data = array();
264
+ }
265
+
266
+ $this->data[ $this->in_tag ] = ! empty( $this->cdata ) ? $this->cdata : '';
267
+ $this->in_tag = false;
268
  }
269
  }
270
 
parsers/class-wxr-parser.php CHANGED
@@ -17,24 +17,27 @@ class WXR_Parser {
17
  $result = $parser->parse( $file );
18
 
19
  // If SimpleXML succeeds or this is an invalid WXR file then return the results
20
- if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' != $result->get_error_code() )
21
  return $result;
22
- } else if ( extension_loaded( 'xml' ) ) {
 
23
  $parser = new WXR_Parser_XML;
24
  $result = $parser->parse( $file );
25
 
26
  // If XMLParser succeeds or this is an invalid WXR file then return the results
27
- if ( ! is_wp_error( $result ) || 'XML_parse_error' != $result->get_error_code() )
28
  return $result;
 
29
  }
30
 
31
  // We have a malformed XML file, so display the error and fallthrough to regex
32
- if ( isset($result) && defined('IMPORT_DEBUG') && IMPORT_DEBUG ) {
33
  echo '<pre>';
34
  if ( 'SimpleXML_parse_error' == $result->get_error_code() ) {
35
- foreach ( $result->get_error_data() as $error )
36
  echo $error->line . ':' . $error->column . ' ' . esc_html( $error->message ) . "\n";
37
- } else if ( 'XML_parse_error' == $result->get_error_code() ) {
 
38
  $error = $result->get_error_data();
39
  echo $error[0] . ':' . $error[1] . ' ' . esc_html( $error[2] );
40
  }
17
  $result = $parser->parse( $file );
18
 
19
  // If SimpleXML succeeds or this is an invalid WXR file then return the results
20
+ if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' != $result->get_error_code() ) {
21
  return $result;
22
+ }
23
+ } elseif ( extension_loaded( 'xml' ) ) {
24
  $parser = new WXR_Parser_XML;
25
  $result = $parser->parse( $file );
26
 
27
  // If XMLParser succeeds or this is an invalid WXR file then return the results
28
+ if ( ! is_wp_error( $result ) || 'XML_parse_error' != $result->get_error_code() ) {
29
  return $result;
30
+ }
31
  }
32
 
33
  // We have a malformed XML file, so display the error and fallthrough to regex
34
+ if ( isset( $result ) && defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
35
  echo '<pre>';
36
  if ( 'SimpleXML_parse_error' == $result->get_error_code() ) {
37
+ foreach ( $result->get_error_data() as $error ) {
38
  echo $error->line . ':' . $error->column . ' ' . esc_html( $error->message ) . "\n";
39
+ }
40
+ } elseif ( 'XML_parse_error' == $result->get_error_code() ) {
41
  $error = $result->get_error_data();
42
  echo $error[0] . ':' . $error[1] . ' ' . esc_html( $error[2] );
43
  }
readme.txt CHANGED
@@ -1,118 +1,128 @@
1
- === WordPress Importer ===
2
- Contributors: wordpressdotorg
3
- Donate link: https://wordpressfoundation.org/donate/
4
- Tags: importer, wordpress
5
- Requires at least: 3.7
6
- Tested up to: 5.4
7
- Stable tag: 0.7
8
- License: GPLv2 or later
9
- License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
-
11
- Import posts, pages, comments, custom fields, categories, tags and more from a WordPress export file.
12
-
13
- == Description ==
14
-
15
- The WordPress Importer will import the following content from a WordPress export file:
16
-
17
- * Posts, pages and other custom post types
18
- * Comments and comment meta
19
- * Custom fields and post meta
20
- * Categories, tags and terms from custom taxonomies and term meta
21
- * Authors
22
-
23
- For further information and instructions please see the [documention on Importing Content](https://wordpress.org/support/article/importing-content/#wordpress).
24
-
25
- == Installation ==
26
-
27
- The quickest method for installing the importer is:
28
-
29
- 1. Visit Tools -> Import in the WordPress dashboard
30
- 1. Click on the WordPress link in the list of importers
31
- 1. Click "Install Now"
32
- 1. Finally click "Activate Plugin & Run Importer"
33
-
34
- If you would prefer to do things manually then follow these instructions:
35
-
36
- 1. Upload the `wordpress-importer` folder to the `/wp-content/plugins/` directory
37
- 1. Activate the plugin through the 'Plugins' menu in WordPress
38
- 1. Go to the Tools -> Import screen, click on WordPress
39
-
40
- == Changelog ==
41
-
42
- = 0.7 =
43
- * Update minimum WordPress requirement to 3.7 and ensure compatibility with PHP 7.4.
44
- * Fix bug that caused not importing term meta.
45
- * Fix bug that caused slashes to be stripped from imported meta data.
46
- * Fix bug that prevented import of serialized meta data.
47
- * Fix file size check after download of remote files with HTTP compression enabled.
48
- * Improve accessibility of form fields by adding missing labels.
49
- * Improve imports for remote file URLs without name and/or extension.
50
- * Add support for `wp:base_blog_url` field to allow importing multiple files with WP-CLI.
51
- * Add support for term meta parsing when using the regular expressions or XML parser.
52
- * Developers: All PHP classes have been moved into their own files.
53
- * Developers: Allow to change `IMPORT_DEBUG` via `wp-config.php` and change default value to the value of `WP_DEBUG`.
54
-
55
- = 0.6.4 =
56
- * Improve PHP7 compatibility.
57
- * Fix bug that caused slashes to be stripped from imported comments.
58
- * Fix for various deprecation notices including `wp_get_http()` and `screen_icon()`.
59
- * Fix for importing export files with multiline term meta data.
60
-
61
- = 0.6.3 =
62
- * Add support for import term metadata.
63
- * Fix bug that caused slashes to be stripped from imported content.
64
- * Fix bug that caused characters to be stripped inside of CDATA in some cases.
65
- * Fix PHP notices.
66
-
67
- = 0.6.2 =
68
- * Add `wp_import_existing_post` filter, see [Trac ticket #33721](https://core.trac.wordpress.org/ticket/33721).
69
-
70
- = 0.6 =
71
- * Support for WXR 1.2 and multiple CDATA sections
72
- * Post aren't duplicates if their post_type's are different
73
-
74
- = 0.5.2 =
75
- * Double check that the uploaded export file exists before processing it. This prevents incorrect error messages when
76
- an export file is uploaded to a server with bad permissions and WordPress 3.3 or 3.3.1 is being used.
77
-
78
- = 0.5 =
79
- * Import comment meta (requires export from WordPress 3.2)
80
- * Minor bugfixes and enhancements
81
-
82
- = 0.4 =
83
- * Map comment user_id where possible
84
- * Import attachments from `wp:attachment_url`
85
- * Upload attachments to correct directory
86
- * Remap resized image URLs correctly
87
-
88
- = 0.3 =
89
- * Use an XML Parser if possible
90
- * Proper import support for nav menus
91
- * ... and much more, see [Trac ticket #15197](https://core.trac.wordpress.org/ticket/15197)
92
-
93
- = 0.1 =
94
- * Initial release
95
-
96
- == Frequently Asked Questions ==
97
-
98
- = Help! I'm getting out of memory errors or a blank screen. =
99
- If your exported file is very large, the import script may run into your host's configured memory limit for PHP.
100
-
101
- A message like "Fatal error: Allowed memory size of 8388608 bytes exhausted" indicates that the script can't successfully import your XML file under the current PHP memory limit. If you have access to the php.ini file, you can manually increase the limit; if you do not (your WordPress installation is hosted on a shared server, for instance), you might have to break your exported XML file into several smaller pieces and run the import script one at a time.
102
-
103
- For those with shared hosting, the best alternative may be to consult hosting support to determine the safest approach for running the import. A host may be willing to temporarily lift the memory limit and/or run the process directly from their end.
104
-
105
- -- [Support Article: Importing Content](https://wordpress.org/support/article/importing-content/#before-importing)
106
-
107
- == Filters ==
108
-
109
- The importer has a couple of filters to allow you to completely enable/block certain features:
110
-
111
- * `import_allow_create_users`: return false if you only want to allow mapping to existing users
112
- * `import_allow_fetch_attachments`: return false if you do not wish to allow importing and downloading of attachments
113
- * `import_attachment_size_limit`: return an integer value for the maximum file size in bytes to save (default is 0, which is unlimited)
114
-
115
- There are also a few actions available to hook into:
116
-
117
- * `import_start`: occurs after the export file has been uploaded and author import settings have been chosen
118
- * `import_end`: called after the last output from the importer
 
 
 
 
 
 
 
 
 
 
1
+ === WordPress Importer ===
2
+ Contributors: wordpressdotorg
3
+ Donate link: https://wordpressfoundation.org/donate/
4
+ Tags: importer, wordpress
5
+ Requires at least: 5.2
6
+ Tested up to: 6.1
7
+ Requires PHP: 5.6
8
+ Stable tag: 0.8
9
+ License: GPLv2 or later
10
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
+
12
+ Import posts, pages, comments, custom fields, categories, tags and more from a WordPress export file.
13
+
14
+ == Description ==
15
+
16
+ The WordPress Importer will import the following content from a WordPress export file:
17
+
18
+ * Posts, pages and other custom post types
19
+ * Comments and comment meta
20
+ * Custom fields and post meta
21
+ * Categories, tags and terms from custom taxonomies and term meta
22
+ * Authors
23
+
24
+ For further information and instructions please see the [documention on Importing Content](https://wordpress.org/support/article/importing-content/#wordpress).
25
+
26
+ == Installation ==
27
+
28
+ The quickest method for installing the importer is:
29
+
30
+ 1. Visit Tools -> Import in the WordPress dashboard
31
+ 1. Click on the WordPress link in the list of importers
32
+ 1. Click "Install Now"
33
+ 1. Finally click "Activate Plugin & Run Importer"
34
+
35
+ If you would prefer to do things manually then follow these instructions:
36
+
37
+ 1. Upload the `wordpress-importer` folder to the `/wp-content/plugins/` directory
38
+ 1. Activate the plugin through the 'Plugins' menu in WordPress
39
+ 1. Go to the Tools -> Import screen, click on WordPress
40
+
41
+ == Changelog ==
42
+
43
+ = 0.8 =
44
+ * Update minimum WordPress requirement to 5.2.
45
+ * Update minimum PHP requirement to 5.6.
46
+ * Update compatibility tested-up-to to WordPress 6.1.
47
+ * PHP 8.0, 8.1, and 8.2 compatibility fixes.
48
+ * Fix a bug causing blank lines in content to be ignored when using the Regex Parser.
49
+ * Fix a bug resulting in a PHP fatal error when IMPORT_DEBUG is enabled and a category creation error occurs.
50
+ * Improved Unit testing & automated testing.
51
+
52
+ = 0.7 =
53
+ * Update minimum WordPress requirement to 3.7 and ensure compatibility with PHP 7.4.
54
+ * Fix bug that caused not importing term meta.
55
+ * Fix bug that caused slashes to be stripped from imported meta data.
56
+ * Fix bug that prevented import of serialized meta data.
57
+ * Fix file size check after download of remote files with HTTP compression enabled.
58
+ * Improve accessibility of form fields by adding missing labels.
59
+ * Improve imports for remote file URLs without name and/or extension.
60
+ * Add support for `wp:base_blog_url` field to allow importing multiple files with WP-CLI.
61
+ * Add support for term meta parsing when using the regular expressions or XML parser.
62
+ * Developers: All PHP classes have been moved into their own files.
63
+ * Developers: Allow to change `IMPORT_DEBUG` via `wp-config.php` and change default value to the value of `WP_DEBUG`.
64
+
65
+ = 0.6.4 =
66
+ * Improve PHP7 compatibility.
67
+ * Fix bug that caused slashes to be stripped from imported comments.
68
+ * Fix for various deprecation notices including `wp_get_http()` and `screen_icon()`.
69
+ * Fix for importing export files with multiline term meta data.
70
+
71
+ = 0.6.3 =
72
+ * Add support for import term metadata.
73
+ * Fix bug that caused slashes to be stripped from imported content.
74
+ * Fix bug that caused characters to be stripped inside of CDATA in some cases.
75
+ * Fix PHP notices.
76
+
77
+ = 0.6.2 =
78
+ * Add `wp_import_existing_post` filter, see [Trac ticket #33721](https://core.trac.wordpress.org/ticket/33721).
79
+
80
+ = 0.6 =
81
+ * Support for WXR 1.2 and multiple CDATA sections
82
+ * Post aren't duplicates if their post_type's are different
83
+
84
+ = 0.5.2 =
85
+ * Double check that the uploaded export file exists before processing it. This prevents incorrect error messages when
86
+ an export file is uploaded to a server with bad permissions and WordPress 3.3 or 3.3.1 is being used.
87
+
88
+ = 0.5 =
89
+ * Import comment meta (requires export from WordPress 3.2)
90
+ * Minor bugfixes and enhancements
91
+
92
+ = 0.4 =
93
+ * Map comment user_id where possible
94
+ * Import attachments from `wp:attachment_url`
95
+ * Upload attachments to correct directory
96
+ * Remap resized image URLs correctly
97
+
98
+ = 0.3 =
99
+ * Use an XML Parser if possible
100
+ * Proper import support for nav menus
101
+ * ... and much more, see [Trac ticket #15197](https://core.trac.wordpress.org/ticket/15197)
102
+
103
+ = 0.1 =
104
+ * Initial release
105
+
106
+ == Frequently Asked Questions ==
107
+
108
+ = Help! I'm getting out of memory errors or a blank screen. =
109
+ If your exported file is very large, the import script may run into your host's configured memory limit for PHP.
110
+
111
+ A message like "Fatal error: Allowed memory size of 8388608 bytes exhausted" indicates that the script can't successfully import your XML file under the current PHP memory limit. If you have access to the php.ini file, you can manually increase the limit; if you do not (your WordPress installation is hosted on a shared server, for instance), you might have to break your exported XML file into several smaller pieces and run the import script one at a time.
112
+
113
+ For those with shared hosting, the best alternative may be to consult hosting support to determine the safest approach for running the import. A host may be willing to temporarily lift the memory limit and/or run the process directly from their end.
114
+
115
+ -- [Support Article: Importing Content](https://wordpress.org/support/article/importing-content/#before-importing)
116
+
117
+ == Filters ==
118
+
119
+ The importer has a couple of filters to allow you to completely enable/block certain features:
120
+
121
+ * `import_allow_create_users`: return false if you only want to allow mapping to existing users
122
+ * `import_allow_fetch_attachments`: return false if you do not wish to allow importing and downloading of attachments
123
+ * `import_attachment_size_limit`: return an integer value for the maximum file size in bytes to save (default is 0, which is unlimited)
124
+
125
+ There are also a few actions available to hook into:
126
+
127
+ * `import_start`: occurs after the export file has been uploaded and author import settings have been chosen
128
+ * `import_end`: called after the last output from the importer
wordpress-importer.php CHANGED
@@ -1,15 +1,18 @@
1
  <?php
2
  /*
3
- Plugin Name: WordPress Importer
4
- Plugin URI: https://wordpress.org/plugins/wordpress-importer/
5
- Description: Import posts, pages, comments, custom fields, categories, tags and more from a WordPress export file.
6
- Author: wordpressdotorg
7
- Author URI: https://wordpress.org/
8
- Version: 0.7
9
- Text Domain: wordpress-importer
10
- License: GPLv2 or later
11
- License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
- */
 
 
 
13
 
14
  if ( ! defined( 'WP_LOAD_IMPORTERS' ) ) {
15
  return;
@@ -25,8 +28,9 @@ require_once ABSPATH . 'wp-admin/includes/import.php';
25
 
26
  if ( ! class_exists( 'WP_Importer' ) ) {
27
  $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
28
- if ( file_exists( $class_wp_importer ) )
29
  require $class_wp_importer;
 
30
  }
31
 
32
  /** Functions missing in older WordPress versions. */
@@ -55,6 +59,7 @@ function wordpress_importer_init() {
55
  * @global WP_Import $wp_import
56
  */
57
  $GLOBALS['wp_import'] = new WP_Import();
58
- register_importer( 'wordpress', 'WordPress', __('Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'wordpress-importer'), array( $GLOBALS['wp_import'], 'dispatch' ) );
 
59
  }
60
  add_action( 'admin_init', 'wordpress_importer_init' );
1
  <?php
2
  /*
3
+ * @wordpress-plugin
4
+ * Plugin Name: WordPress Importer
5
+ * Plugin URI: https://wordpress.org/plugins/wordpress-importer/
6
+ * Description: Import posts, pages, comments, custom fields, categories, tags and more from a WordPress export file.
7
+ * Author: wordpressdotorg
8
+ * Author URI: https://wordpress.org/
9
+ * Version: 0.8
10
+ * Requires at least: 5.2
11
+ * Requires PHP: 5.6
12
+ * Text Domain: wordpress-importer
13
+ * License: GPLv2 or later
14
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
15
+ */
16
 
17
  if ( ! defined( 'WP_LOAD_IMPORTERS' ) ) {
18
  return;
28
 
29
  if ( ! class_exists( 'WP_Importer' ) ) {
30
  $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
31
+ if ( file_exists( $class_wp_importer ) ) {
32
  require $class_wp_importer;
33
+ }
34
  }
35
 
36
  /** Functions missing in older WordPress versions. */
59
  * @global WP_Import $wp_import
60
  */
61
  $GLOBALS['wp_import'] = new WP_Import();
62
+ // phpcs:ignore WordPress.WP.CapitalPDangit
63
+ register_importer( 'wordpress', 'WordPress', __( 'Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'wordpress-importer' ), array( $GLOBALS['wp_import'], 'dispatch' ) );
64
  }
65
  add_action( 'admin_init', 'wordpress_importer_init' );