ThemeGrill Demo Importer - Version 1.6.5

Version Description

  • 23-07-2020 =
  • Fix - Demo not importing completely in certain conditions.
Download this release

Release Info

Developer themegrilldev
Plugin Icon 128x128 ThemeGrill Demo Importer
Version 1.6.5
Comparing to
See all releases

Code changes from version 1.6.4 to 1.6.5

includes/class-themegrill-demo-importer.php CHANGED
@@ -20,7 +20,7 @@ final class ThemeGrill_Demo_Importer {
20
  *
21
  * @var string
22
  */
23
- public $version = '1.6.4';
24
 
25
  /**
26
  * Theme single instance of this class.
20
  *
21
  * @var string
22
  */
23
+ public $version = '1.6.5';
24
 
25
  /**
26
  * Theme single instance of this class.
includes/importers/wordpress-importer/class-wxr-importer.php CHANGED
@@ -20,8 +20,17 @@ if ( ! class_exists( 'WP_Importer' ) ) {
20
  /** Display verbose errors */
21
  define( 'IMPORT_DEBUG', false );
22
 
23
- // Include WXR file parsers.
24
- require dirname( __FILE__ ) . '/class-wxr-parsers.php';
 
 
 
 
 
 
 
 
 
25
 
26
  /**
27
  * TG_WXR_Importer Class.
@@ -33,26 +42,26 @@ class TG_WXR_Importer extends WP_Importer {
33
 
34
  // information to import from WXR file
35
  var $version;
36
- var $authors = array();
37
- var $posts = array();
38
- var $terms = array();
39
  var $categories = array();
40
- var $tags = array();
41
- var $base_url = '';
42
 
43
  // mappings from old information to new
44
- var $processed_authors = array();
45
- var $author_mapping = array();
46
- var $processed_terms = array();
47
- var $processed_posts = array();
48
- var $post_orphans = array();
49
  var $processed_menu_items = array();
50
- var $menu_item_orphans = array();
51
- var $missing_menu_items = array();
52
 
53
  var $fetch_attachments = false;
54
- var $url_remap = array();
55
- var $featured_images = array();
56
 
57
  /**
58
  * Registered callback function for the WordPress Importer
@@ -69,16 +78,15 @@ class TG_WXR_Importer extends WP_Importer {
69
  break;
70
  case 1:
71
  check_admin_referer( 'import-upload' );
72
- if ( $this->handle_upload() ) {
73
  $this->import_options();
74
- }
75
  break;
76
  case 2:
77
  check_admin_referer( 'import-wordpress' );
78
  $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() );
79
- $this->id = (int) $_POST['import_id'];
80
- $file = get_attached_file( $this->id );
81
- set_time_limit( 0 );
82
  $this->import( $file );
83
  break;
84
  }
@@ -120,7 +128,7 @@ class TG_WXR_Importer extends WP_Importer {
120
  * @param string $file Path to the WXR file for importing
121
  */
122
  function import_start( $file ) {
123
- if ( ! is_file( $file ) ) {
124
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
125
  echo __( 'The file does not exist, please try again.', 'themegrill-demo-importer' ) . '</p>';
126
  $this->footer();
@@ -138,11 +146,11 @@ class TG_WXR_Importer extends WP_Importer {
138
 
139
  $this->version = $import_data['version'];
140
  $this->get_authors_from_import( $import_data );
141
- $this->posts = $import_data['posts'];
142
- $this->terms = $import_data['terms'];
143
  $this->categories = $import_data['categories'];
144
- $this->tags = $import_data['tags'];
145
- $this->base_url = esc_url( $import_data['base_url'] );
146
 
147
  wp_defer_term_counting( true );
148
  wp_defer_comment_counting( true );
@@ -184,14 +192,14 @@ class TG_WXR_Importer extends WP_Importer {
184
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
185
  echo esc_html( $file['error'] ) . '</p>';
186
  return false;
187
- } elseif ( ! file_exists( $file['file'] ) ) {
188
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
189
  printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'themegrill-demo-importer' ), esc_html( $file['file'] ) );
190
  echo '</p>';
191
  return false;
192
  }
193
 
194
- $this->id = (int) $file['id'];
195
  $import_data = $this->parse( $file['file'] );
196
  if ( is_wp_error( $import_data ) ) {
197
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
@@ -202,7 +210,7 @@ class TG_WXR_Importer extends WP_Importer {
202
  $this->version = $import_data['version'];
203
  if ( $this->version > $this->max_wxr_version ) {
204
  echo '<div class="error"><p><strong>';
205
- printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'themegrill-demo-importer' ), esc_html( $import_data['version'] ) );
206
  echo '</strong></p></div>';
207
  }
208
 
@@ -222,7 +230,7 @@ class TG_WXR_Importer extends WP_Importer {
222
  function get_authors_from_import( $import_data ) {
223
  if ( ! empty( $import_data['authors'] ) ) {
224
  $this->authors = $import_data['authors'];
225
- // no author information, grab it from the posts
226
  } else {
227
  foreach ( $import_data['posts'] as $post ) {
228
  $login = sanitize_user( $post['post_author'], true );
@@ -232,12 +240,11 @@ class TG_WXR_Importer extends WP_Importer {
232
  continue;
233
  }
234
 
235
- if ( ! isset( $this->authors[ $login ] ) ) {
236
- $this->authors[ $login ] = array(
237
- 'author_login' => $login,
238
- 'author_display_name' => $post['post_author'],
239
  );
240
- }
241
  }
242
  }
243
  }
@@ -248,25 +255,25 @@ class TG_WXR_Importer extends WP_Importer {
248
  */
249
  function import_options() {
250
  $j = 0;
251
- ?>
252
  <form action="<?php echo admin_url( 'admin.php?import=wordpress&amp;step=2' ); ?>" method="post">
253
- <?php wp_nonce_field( 'import-wordpress' ); ?>
254
  <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
255
 
256
- <?php if ( ! empty( $this->authors ) ) : ?>
257
  <h3><?php _e( 'Assign Authors', 'themegrill-demo-importer' ); ?></h3>
258
- <p><?php _e( 'To make it easier 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. For example, you may want to import all the entries as <code>admin</code>s entries.', 'themegrill-demo-importer' ); ?></p>
259
- <?php if ( $this->allow_create_users() ) : ?>
260
- <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.', 'themegrill-demo-importer' ), esc_html( get_option( 'default_role' ) ) ); ?></p>
261
  <?php endif; ?>
262
  <ol id="authors">
263
- <?php foreach ( $this->authors as $author ) : ?>
264
  <li><?php $this->author_select( $j++, $author ); ?></li>
265
  <?php endforeach; ?>
266
  </ol>
267
  <?php endif; ?>
268
 
269
- <?php if ( $this->allow_fetch_attachments() ) : ?>
270
  <h3><?php _e( 'Import Attachments', 'themegrill-demo-importer' ); ?></h3>
271
  <p>
272
  <input type="checkbox" value="1" name="fetch_attachments" id="import-attachments" />
@@ -276,30 +283,28 @@ class TG_WXR_Importer extends WP_Importer {
276
 
277
  <p class="submit"><input type="submit" class="button" value="<?php esc_attr_e( 'Submit', 'themegrill-demo-importer' ); ?>" /></p>
278
  </form>
279
- <?php
280
  }
281
 
282
  /**
283
  * Display import options for an individual author. That is, either create
284
  * a new user based on import info or map to an existing user
285
  *
286
- * @param int $n Index for each author in the form
287
  * @param array $author Author information, e.g. login, display name, email
288
  */
289
  function author_select( $n, $author ) {
290
  _e( 'Import author:', 'themegrill-demo-importer' );
291
  echo ' <strong>' . esc_html( $author['author_display_name'] );
292
- if ( $this->version != '1.0' ) {
293
- echo ' (' . esc_html( $author['author_login'] ) . ')';
294
- }
295
  echo '</strong><br />';
296
 
297
- if ( $this->version != '1.0' ) {
298
  echo '<div style="margin-left:18px">';
299
- }
300
 
301
  $create_users = $this->allow_create_users();
302
  if ( $create_users ) {
 
303
  if ( $this->version != '1.0' ) {
304
  _e( 'or create new user with login name:', 'themegrill-demo-importer' );
305
  $value = '';
@@ -307,30 +312,32 @@ class TG_WXR_Importer extends WP_Importer {
307
  _e( 'as a new user:', 'themegrill-demo-importer' );
308
  $value = esc_attr( sanitize_user( $author['author_login'], true ) );
309
  }
 
310
 
311
- echo ' <input type="text" name="user_new[' . $n . ']" value="' . $value . '" /><br />';
312
  }
313
 
 
314
  if ( ! $create_users && $this->version == '1.0' ) {
315
  _e( 'assign posts to an existing user:', 'themegrill-demo-importer' );
316
  } else {
317
  _e( 'or assign posts to an existing user:', 'themegrill-demo-importer' );
318
  }
319
- wp_dropdown_users(
320
- array(
321
- 'name' => "user_map[$n]",
322
- 'multi' => true,
323
- 'show_option_all' => __(
324
- '- Select -',
325
- 'themegrill-demo-importer'
326
- ),
327
- )
328
- );
329
- echo '<input type="hidden" name="imported_authors[' . $n . ']" value="' . esc_attr( $author['author_login'] ) . '" />';
330
 
331
- if ( $this->version != '1.0' ) {
 
 
332
  echo '</div>';
333
- }
334
  }
335
 
336
  /**
@@ -339,60 +346,55 @@ class TG_WXR_Importer extends WP_Importer {
339
  * or falls back to the current user in case of error with either of the previous
340
  */
341
  function get_author_mapping() {
342
- if ( ! isset( $_POST['imported_authors'] ) ) {
343
  return;
344
- }
345
 
346
  $create_users = $this->allow_create_users();
347
 
348
  foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
349
  // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
350
  $santized_old_login = sanitize_user( $old_login, true );
351
- $old_id = isset( $this->authors[ $old_login ]['author_id'] ) ? intval( $this->authors[ $old_login ]['author_id'] ) : false;
352
 
353
- if ( ! empty( $_POST['user_map'][ $i ] ) ) {
354
- $user = get_userdata( intval( $_POST['user_map'][ $i ] ) );
355
  if ( isset( $user->ID ) ) {
356
- if ( $old_id ) {
357
- $this->processed_authors[ $old_id ] = $user->ID;
358
- }
359
- $this->author_mapping[ $santized_old_login ] = $user->ID;
360
  }
361
- } elseif ( $create_users ) {
362
- if ( ! empty( $_POST['user_new'][ $i ] ) ) {
363
- $user_id = wp_create_user( $_POST['user_new'][ $i ], wp_generate_password() );
364
- } elseif ( $this->version != '1.0' ) {
365
  $user_data = array(
366
- 'user_login' => $old_login,
367
- 'user_pass' => wp_generate_password(),
368
- 'user_email' => isset( $this->authors[ $old_login ]['author_email'] ) ? $this->authors[ $old_login ]['author_email'] : '',
369
- 'display_name' => $this->authors[ $old_login ]['author_display_name'],
370
- 'first_name' => isset( $this->authors[ $old_login ]['author_first_name'] ) ? $this->authors[ $old_login ]['author_first_name'] : '',
371
- 'last_name' => isset( $this->authors[ $old_login ]['author_last_name'] ) ? $this->authors[ $old_login ]['author_last_name'] : '',
372
  );
373
- $user_id = wp_insert_user( $user_data );
374
  }
375
 
376
  if ( ! is_wp_error( $user_id ) ) {
377
- if ( $old_id ) {
378
- $this->processed_authors[ $old_id ] = $user_id;
379
- }
380
- $this->author_mapping[ $santized_old_login ] = $user_id;
381
  } else {
382
- printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'themegrill-demo-importer' ), esc_html( $this->authors[ $old_login ]['author_display_name'] ) );
383
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
384
  echo ' ' . $user_id->get_error_message();
385
- }
386
  echo '<br />';
387
  }
388
  }
389
 
390
  // failsafe: if the user_id was invalid, default to the current user
391
- if ( ! isset( $this->author_mapping[ $santized_old_login ] ) ) {
392
- if ( $old_id ) {
393
- $this->processed_authors[ $old_id ] = (int) get_current_user_id();
394
- }
395
- $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
396
  }
397
  }
398
  }
@@ -405,48 +407,42 @@ class TG_WXR_Importer extends WP_Importer {
405
  function process_categories() {
406
  $this->categories = apply_filters( 'wp_import_categories', $this->categories );
407
 
408
- if ( empty( $this->categories ) ) {
409
  return;
410
- }
411
 
412
  foreach ( $this->categories as $cat ) {
413
  // if the category already exists leave it alone
414
  $term_id = term_exists( $cat['category_nicename'], 'category' );
415
  if ( $term_id ) {
416
- if ( is_array( $term_id ) ) {
417
- $term_id = $term_id['term_id'];
418
- }
419
- if ( isset( $cat['term_id'] ) ) {
420
- $this->processed_terms[ intval( $cat['term_id'] ) ] = (int) $term_id;
421
- }
422
  continue;
423
  }
424
 
425
- $category_parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] );
426
- $category_description = isset( $cat['category_description'] ) ? $cat['category_description'] : '';
427
- $catarr = array(
 
428
  'category_nicename' => $cat['category_nicename'],
429
- 'category_parent' => $category_parent,
430
- 'cat_name' => $cat['cat_name'],
431
- 'category_description' => $category_description,
432
  );
433
- $catarr = wp_slash( $catarr );
434
 
435
- $id = wp_insert_category( $catarr );
436
- if ( ! is_wp_error( $id ) ) {
437
- if ( isset( $cat['term_id'] ) ) {
438
- $this->processed_terms[ intval( $cat['term_id'] ) ] = $id;
439
- }
440
  } else {
441
- printf( __( 'Failed to import category %s', 'themegrill-demo-importer' ), esc_html( $cat['category_nicename'] ) );
442
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
443
  echo ': ' . $id->get_error_message();
444
- }
445
  echo '<br />';
446
  continue;
447
  }
448
 
449
- $this->process_termmeta( $cat, $id['term_id'] );
450
  }
451
 
452
  unset( $this->categories );
@@ -460,40 +456,33 @@ class TG_WXR_Importer extends WP_Importer {
460
  function process_tags() {
461
  $this->tags = apply_filters( 'wp_import_tags', $this->tags );
462
 
463
- if ( empty( $this->tags ) ) {
464
  return;
465
- }
466
 
467
  foreach ( $this->tags as $tag ) {
468
  // if the tag already exists leave it alone
469
  $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
470
  if ( $term_id ) {
471
- if ( is_array( $term_id ) ) {
472
- $term_id = $term_id['term_id'];
473
- }
474
- if ( isset( $tag['term_id'] ) ) {
475
- $this->processed_terms[ intval( $tag['term_id'] ) ] = (int) $term_id;
476
- }
477
  continue;
478
  }
479
 
480
- $tag = wp_slash( $tag );
481
- $tag_desc = isset( $tag['tag_description'] ) ? $tag['tag_description'] : '';
482
- $tagarr = array(
483
  'slug' => $tag['tag_slug'],
484
- 'description' => $tag_desc,
485
  );
486
 
487
- $id = wp_insert_term( $tag['tag_name'], 'post_tag', $tagarr );
488
  if ( ! is_wp_error( $id ) ) {
489
- if ( isset( $tag['term_id'] ) ) {
490
- $this->processed_terms[ intval( $tag['term_id'] ) ] = $id['term_id'];
491
- }
492
  } else {
493
- printf( __( 'Failed to import post tag %s', 'themegrill-demo-importer' ), esc_html( $tag['tag_name'] ) );
494
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
495
  echo ': ' . $id->get_error_message();
496
- }
497
  echo '<br />';
498
  continue;
499
  }
@@ -512,20 +501,16 @@ class TG_WXR_Importer extends WP_Importer {
512
  function process_terms() {
513
  $this->terms = apply_filters( 'wp_import_terms', $this->terms );
514
 
515
- if ( empty( $this->terms ) ) {
516
  return;
517
- }
518
 
519
  foreach ( $this->terms as $term ) {
520
  // if the term already exists in the correct taxonomy leave it alone
521
  $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
522
  if ( $term_id ) {
523
- if ( is_array( $term_id ) ) {
524
- $term_id = $term_id['term_id'];
525
- }
526
- if ( isset( $term['term_id'] ) ) {
527
- $this->processed_terms[ intval( $term['term_id'] ) ] = (int) $term_id;
528
- }
529
  continue;
530
  }
531
 
@@ -537,24 +522,22 @@ class TG_WXR_Importer extends WP_Importer {
537
  $parent = $parent['term_id'];
538
  }
539
  }
540
- $term = wp_slash( $term );
541
  $description = isset( $term['term_description'] ) ? $term['term_description'] : '';
542
- $termarr = array(
543
  'slug' => $term['slug'],
544
- 'description' => $description,
545
- 'parent' => intval( $parent ),
546
  );
547
 
548
- $id = wp_insert_term( $term['term_name'], $term['term_taxonomy'], $termarr );
549
  if ( ! is_wp_error( $id ) ) {
550
- if ( isset( $term['term_id'] ) ) {
551
- $this->processed_terms[ intval( $term['term_id'] ) ] = $id['term_id'];
552
- }
553
  } else {
554
- printf( __( 'Failed to import %1$s %2$s', 'themegrill-demo-importer' ), esc_html( $term['term_taxonomy'] ), esc_html( $term['term_name'] ) );
555
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
556
  echo ': ' . $id->get_error_message();
557
- }
558
  echo '<br />';
559
  continue;
560
  }
@@ -574,6 +557,10 @@ class TG_WXR_Importer extends WP_Importer {
574
  * @param int $term_id ID of the newly created term.
575
  */
576
  protected function process_termmeta( $term, $term_id ) {
 
 
 
 
577
  if ( ! isset( $term['termmeta'] ) ) {
578
  $term['termmeta'] = array();
579
  }
@@ -611,7 +598,7 @@ class TG_WXR_Importer extends WP_Importer {
611
  // Export gets meta straight from the DB so could have a serialized string
612
  $value = maybe_unserialize( $meta['value'] );
613
 
614
- add_term_meta( $term_id, $key, $value );
615
 
616
  /**
617
  * Fires after term meta is imported.
@@ -641,23 +628,18 @@ class TG_WXR_Importer extends WP_Importer {
641
  $post = apply_filters( 'wp_import_post_data_raw', $post );
642
 
643
  if ( ! post_type_exists( $post['post_type'] ) ) {
644
- printf(
645
- __( 'Failed to import &#8220;%1$s&#8221;: Invalid post type %2$s', 'themegrill-demo-importer' ),
646
- esc_html( $post['post_title'] ),
647
- esc_html( $post['post_type'] )
648
- );
649
  echo '<br />';
650
  do_action( 'wp_import_post_exists', $post );
651
  continue;
652
  }
653
 
654
- if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) {
655
  continue;
656
- }
657
 
658
- if ( $post['status'] == 'auto-draft' ) {
659
  continue;
660
- }
661
 
662
  if ( 'nav_menu_item' == $post['post_type'] ) {
663
  $this->process_menu_item( $post );
@@ -683,67 +665,56 @@ class TG_WXR_Importer extends WP_Importer {
683
  $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
684
 
685
  if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
686
- printf( __( '%1$s &#8220;%2$s&#8221; already exists.', 'themegrill-demo-importer' ), $post_type_object->labels->singular_name, esc_html( $post['post_title'] ) );
687
  echo '<br />';
688
- $comment_post_ID = $post_id = $post_exists;
689
  $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
690
  } else {
691
  $post_parent = (int) $post['post_parent'];
692
  if ( $post_parent ) {
693
  // if we already know the parent, map it to the new local ID
694
- if ( isset( $this->processed_posts[ $post_parent ] ) ) {
695
- $post_parent = $this->processed_posts[ $post_parent ];
696
- // otherwise record the parent for later
697
  } else {
698
- $this->post_orphans[ intval( $post['post_id'] ) ] = $post_parent;
699
- $post_parent = 0;
700
  }
701
  }
702
 
703
  // map the post author
704
  $author = sanitize_user( $post['post_author'], true );
705
- if ( isset( $this->author_mapping[ $author ] ) ) {
706
- $author = $this->author_mapping[ $author ];
707
- } else {
708
  $author = (int) get_current_user_id();
709
- }
710
 
711
  $postdata = array(
712
- 'import_id' => $post['post_id'],
713
- 'post_author' => $author,
714
- 'post_date' => $post['post_date'],
715
- 'post_date_gmt' => $post['post_date_gmt'],
716
- 'post_content' => $post['post_content'],
717
- 'post_excerpt' => $post['post_excerpt'],
718
- 'post_title' => $post['post_title'],
719
- 'post_status' => $post['status'],
720
- 'post_name' => $post['post_name'],
721
- 'comment_status' => $post['comment_status'],
722
- 'ping_status' => $post['ping_status'],
723
- 'guid' => $post['guid'],
724
- 'post_parent' => $post_parent,
725
- 'menu_order' => $post['menu_order'],
726
- 'post_type' => $post['post_type'],
727
- 'post_password' => $post['post_password'],
728
  );
729
 
730
  $original_post_ID = $post['post_id'];
731
- $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
732
 
733
  $postdata = wp_slash( $postdata );
734
 
735
  if ( 'attachment' == $postdata['post_type'] ) {
736
- $remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid'];
737
 
738
  // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
739
  // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
740
  $postdata['upload_date'] = $post['post_date'];
741
  if ( isset( $post['postmeta'] ) ) {
742
- foreach ( $post['postmeta'] as $meta ) {
743
  if ( $meta['key'] == '_wp_attached_file' ) {
744
- if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) {
745
  $postdata['upload_date'] = $matches[0];
746
- }
747
  break;
748
  }
749
  }
@@ -756,29 +727,23 @@ class TG_WXR_Importer extends WP_Importer {
756
  }
757
 
758
  if ( is_wp_error( $post_id ) ) {
759
- printf(
760
- __( 'Failed to import %1$s &#8220;%2$s&#8221;', 'themegrill-demo-importer' ),
761
- $post_type_object->labels->singular_name,
762
- esc_html( $post['post_title'] )
763
- );
764
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
765
  echo ': ' . $post_id->get_error_message();
766
- }
767
  echo '<br />';
768
  continue;
769
  }
770
 
771
- if ( $post['is_sticky'] == 1 ) {
772
  stick_post( $post_id );
773
- }
774
  }
775
 
776
  // map pre-import ID to local ID
777
- $this->processed_posts[ intval( $post['post_id'] ) ] = (int) $post_id;
778
 
779
- if ( ! isset( $post['terms'] ) ) {
780
  $post['terms'] = array();
781
- }
782
 
783
  $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
784
 
@@ -787,25 +752,24 @@ class TG_WXR_Importer extends WP_Importer {
787
  $terms_to_set = array();
788
  foreach ( $post['terms'] as $term ) {
789
  // back compat with WXR 1.0 map 'tag' to 'post_tag'
790
- $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
791
  $term_exists = term_exists( $term['slug'], $taxonomy );
792
- $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
793
  if ( ! $term_id ) {
794
  $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
795
  if ( ! is_wp_error( $t ) ) {
796
  $term_id = $t['term_id'];
797
  do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
798
  } else {
799
- printf( __( 'Failed to import %1$s %2$s', 'themegrill-demo-importer' ), esc_html( $taxonomy ), esc_html( $term['name'] ) );
800
- if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
801
  echo ': ' . $t->get_error_message();
802
- }
803
  echo '<br />';
804
  do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
805
  continue;
806
  }
807
  }
808
- $terms_to_set[ $taxonomy ][] = intval( $term_id );
809
  }
810
 
811
  foreach ( $terms_to_set as $tax => $ids ) {
@@ -815,50 +779,53 @@ class TG_WXR_Importer extends WP_Importer {
815
  unset( $post['terms'], $terms_to_set );
816
  }
817
 
818
- if ( ! isset( $post['comments'] ) ) {
819
  $post['comments'] = array();
820
- }
821
 
822
  $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
823
 
824
  // add/update comments
825
  if ( ! empty( $post['comments'] ) ) {
826
- $num_comments = 0;
827
  $inserted_comments = array();
828
  foreach ( $post['comments'] as $comment ) {
829
- $comment_id = $comment['comment_id'];
830
- $newcomments[ $comment_id ]['comment_post_ID'] = $comment_post_ID;
831
- $newcomments[ $comment_id ]['comment_author'] = $comment['comment_author'];
832
- $newcomments[ $comment_id ]['comment_author_email'] = $comment['comment_author_email'];
833
- $newcomments[ $comment_id ]['comment_author_IP'] = $comment['comment_author_IP'];
834
- $newcomments[ $comment_id ]['comment_author_url'] = $comment['comment_author_url'];
835
- $newcomments[ $comment_id ]['comment_date'] = $comment['comment_date'];
836
- $newcomments[ $comment_id ]['comment_date_gmt'] = $comment['comment_date_gmt'];
837
- $newcomments[ $comment_id ]['comment_content'] = $comment['comment_content'];
838
- $newcomments[ $comment_id ]['comment_approved'] = $comment['comment_approved'];
839
- $newcomments[ $comment_id ]['comment_type'] = $comment['comment_type'];
840
- $newcomments[ $comment_id ]['comment_parent'] = $comment['comment_parent'];
841
- $newcomments[ $comment_id ]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
842
- if ( isset( $this->processed_authors[ $comment['comment_user_id'] ] ) ) {
843
- $newcomments[ $comment_id ]['user_id'] = $this->processed_authors[ $comment['comment_user_id'] ];
844
- }
845
  }
846
  ksort( $newcomments );
847
 
848
  foreach ( $newcomments as $key => $comment ) {
849
  // if this is a new post we can skip the comment_exists() check
850
  if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
851
- if ( isset( $inserted_comments[ $comment['comment_parent'] ] ) ) {
852
  $comment['comment_parent'] = $inserted_comments[ $comment['comment_parent'] ];
853
  }
854
- $comment = wp_slash( $comment );
855
- $comment = wp_filter_comment( $comment );
856
- $inserted_comments[ $key ] = wp_insert_comment( $comment );
 
 
 
 
857
  do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $comment_post_ID, $post );
858
 
859
- foreach ( $comment['commentmeta'] as $meta ) {
860
  $value = maybe_unserialize( $meta['value'] );
861
- add_comment_meta( $inserted_comments[ $key ], $meta['key'], $value );
 
862
  }
863
 
864
  $num_comments++;
@@ -867,24 +834,22 @@ class TG_WXR_Importer extends WP_Importer {
867
  unset( $newcomments, $inserted_comments, $post['comments'] );
868
  }
869
 
870
- if ( ! isset( $post['postmeta'] ) ) {
871
  $post['postmeta'] = array();
872
- }
873
 
874
  $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
875
 
876
  // add/update post meta
877
  if ( ! empty( $post['postmeta'] ) ) {
878
  foreach ( $post['postmeta'] as $meta ) {
879
- $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
880
  $value = false;
881
 
882
  if ( '_edit_last' == $key ) {
883
- if ( isset( $this->processed_authors[ intval( $meta['value'] ) ] ) ) {
884
- $value = $this->processed_authors[ intval( $meta['value'] ) ];
885
- } else {
886
  $key = false;
887
- }
888
  }
889
 
890
  if ( $key ) {
@@ -893,13 +858,13 @@ class TG_WXR_Importer extends WP_Importer {
893
  $value = maybe_unserialize( $meta['value'] );
894
  }
895
 
896
- add_post_meta( $post_id, $key, $value );
 
897
  do_action( 'import_post_meta', $post_id, $key, $value );
898
 
899
  // if the post has a featured image, take note of this in case of remap
900
- if ( '_thumbnail_id' == $key ) {
901
- $this->featured_images[ $post_id ] = (int) $value;
902
- }
903
  }
904
  }
905
  }
@@ -920,12 +885,11 @@ class TG_WXR_Importer extends WP_Importer {
920
  */
921
  function process_menu_item( $item ) {
922
  // skip draft, orphaned menu items
923
- if ( 'draft' == $item['status'] ) {
924
  return;
925
- }
926
 
927
  $menu_slug = false;
928
- if ( isset( $item['terms'] ) ) {
929
  // loop through terms, assume first nav_menu term is correct menu
930
  foreach ( $item['terms'] as $term ) {
931
  if ( 'nav_menu' == $term['domain'] ) {
@@ -951,89 +915,76 @@ class TG_WXR_Importer extends WP_Importer {
951
  $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
952
  }
953
 
954
- foreach ( $item['postmeta'] as $meta ) {
955
- if ( version_compare( PHP_VERSION, '7.0.0' ) >= 0 ) {
956
- ${$meta['key']} = $meta['value'];
957
- } else {
958
- $$meta['key'] = $meta['value'];
959
- }
960
- }
961
 
962
- if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[ intval( $_menu_item_object_id ) ] ) ) {
963
- $_menu_item_object_id = $this->processed_terms[ intval( $_menu_item_object_id ) ];
964
- } elseif ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[ intval( $_menu_item_object_id ) ] ) ) {
965
- $_menu_item_object_id = $this->processed_posts[ intval( $_menu_item_object_id ) ];
966
- } elseif ( 'custom' != $_menu_item_type ) {
967
  // associated object is missing or not imported yet, we'll retry later
968
  $this->missing_menu_items[] = $item;
969
  return;
970
  }
971
 
972
- if ( isset( $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ] ) ) {
973
- $_menu_item_menu_item_parent = $this->processed_menu_items[ intval( $_menu_item_menu_item_parent ) ];
974
- } elseif ( $_menu_item_menu_item_parent ) {
975
- $this->menu_item_orphans[ intval( $item['post_id'] ) ] = (int) $_menu_item_menu_item_parent;
976
- $_menu_item_menu_item_parent = 0;
977
  }
978
 
979
  // wp_update_nav_menu_item expects CSS classes as a space separated string
980
  $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
981
- if ( is_array( $_menu_item_classes ) ) {
982
  $_menu_item_classes = implode( ' ', $_menu_item_classes );
983
- }
984
 
985
  $args = array(
986
- 'menu-item-object-id' => $_menu_item_object_id,
987
- 'menu-item-object' => $_menu_item_object,
988
- 'menu-item-parent-id' => $_menu_item_menu_item_parent,
989
- 'menu-item-position' => intval( $item['menu_order'] ),
990
- 'menu-item-type' => $_menu_item_type,
991
- 'menu-item-title' => $item['post_title'],
992
- 'menu-item-url' => $_menu_item_url,
993
  'menu-item-description' => $item['post_content'],
994
- 'menu-item-attr-title' => $item['post_excerpt'],
995
- 'menu-item-target' => $_menu_item_target,
996
- 'menu-item-classes' => $_menu_item_classes,
997
- 'menu-item-xfn' => $_menu_item_xfn,
998
- 'menu-item-status' => $item['status'],
999
  );
1000
 
1001
  $id = wp_update_nav_menu_item( $menu_id, 0, $args );
1002
- if ( $id && ! is_wp_error( $id ) ) {
1003
- $this->processed_menu_items[ intval( $item['post_id'] ) ] = (int) $id;
1004
- }
1005
  }
1006
 
1007
  /**
1008
  * If fetching attachments is enabled then attempt to create a new attachment
1009
  *
1010
- * @param array $post Attachment post details from WXR
1011
  * @param string $url URL to fetch attachment from
1012
  * @return int|WP_Error Post ID on success, WP_Error otherwise
1013
  */
1014
  function process_attachment( $post, $url ) {
1015
- if ( ! $this->fetch_attachments ) {
1016
- return new WP_Error(
1017
- 'attachment_processing_error',
1018
- __( 'Fetching attachments is not enabled', 'themegrill-demo-importer' )
1019
- );
1020
- }
1021
 
1022
  // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
1023
- if ( preg_match( '|^/[\w\W]+$|', $url ) ) {
1024
  $url = rtrim( $this->base_url, '/' ) . $url;
1025
- }
1026
 
1027
  $upload = $this->fetch_remote_file( $url, $post );
1028
- if ( is_wp_error( $upload ) ) {
1029
  return $upload;
1030
- }
1031
 
1032
- if ( $info = wp_check_filetype( $upload['file'] ) ) {
1033
  $post['post_mime_type'] = $info['type'];
1034
- } else {
1035
- return new WP_Error( 'attachment_processing_error', __( 'Invalid file type', 'themegrill-demo-importer' ) );
1036
- }
1037
 
1038
  $post['guid'] = $upload['url'];
1039
 
@@ -1044,12 +995,12 @@ class TG_WXR_Importer extends WP_Importer {
1044
  // remap resized image URLs, works by stripping the extension and remapping the URL stub.
1045
  if ( preg_match( '!^image/!', $info['type'] ) ) {
1046
  $parts = pathinfo( $url );
1047
- $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
1048
 
1049
  $parts_new = pathinfo( $upload['url'] );
1050
- $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
1051
 
1052
- $this->url_remap[ $parts['dirname'] . '/' . $name ] = $parts_new['dirname'] . '/' . $name_new;
1053
  }
1054
 
1055
  return $post_id;
@@ -1059,70 +1010,152 @@ class TG_WXR_Importer extends WP_Importer {
1059
  * Attempt to download a remote file attachment
1060
  *
1061
  * @param string $url URL of item to fetch
1062
- * @param array $post Attachment details
1063
  * @return array|WP_Error Local file location details on success, WP_Error otherwise
1064
  */
1065
  function fetch_remote_file( $url, $post ) {
1066
- // extract the file name and extension from the url
1067
- $file_name = basename( $url );
1068
 
1069
- // get placeholder file in the upload dir with a unique, sanitized filename
1070
- $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
1071
- if ( $upload['error'] ) {
1072
- return new WP_Error( 'upload_dir_error', $upload['error'] );
1073
  }
1074
 
1075
- // fetch the remote url and write it to the placeholder file
1076
- $remote_response = wp_safe_remote_get(
1077
- $url,
1078
- array(
1079
- 'timeout' => 300,
1080
- 'stream' => true,
1081
- 'filename' => $upload['file'],
1082
- )
1083
- );
1084
 
1085
- $headers = wp_remote_retrieve_headers( $remote_response );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1086
 
1087
- // request failed
1088
- if ( ! $headers ) {
1089
- @unlink( $upload['file'] );
1090
- return new WP_Error( 'import_file_error', __( 'Remote server did not respond', 'themegrill-demo-importer' ) );
 
 
 
 
 
 
 
 
 
 
1091
  }
1092
 
1093
- $remote_response_code = wp_remote_retrieve_response_code( $remote_response );
1094
 
1095
- // make sure the fetch was successful
1096
- if ( $remote_response_code != '200' ) {
1097
- @unlink( $upload['file'] );
1098
- return new WP_Error( 'import_file_error', sprintf( __( 'Remote server returned error response %1$d %2$s', 'themegrill-demo-importer' ), esc_html( $remote_response_code ), get_status_header_desc( $remote_response_code ) ) );
1099
  }
1100
 
1101
- $filesize = filesize( $upload['file'] );
1102
 
1103
- if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) {
1104
- @unlink( $upload['file'] );
1105
- return new WP_Error( 'import_file_error', __( 'Remote file is incorrect size', 'themegrill-demo-importer' ) );
1106
  }
1107
 
1108
- if ( 0 == $filesize ) {
1109
- @unlink( $upload['file'] );
1110
- return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'themegrill-demo-importer' ) );
1111
  }
1112
 
1113
  $max_size = (int) $this->max_attachment_size();
1114
  if ( ! empty( $max_size ) && $filesize > $max_size ) {
1115
- @unlink( $upload['file'] );
1116
- return new WP_Error( 'import_file_error', sprintf( __( 'Remote file is too large, limit is %s', 'themegrill-demo-importer' ), size_format( $max_size ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1117
  }
1118
 
 
 
 
 
 
 
 
 
 
 
 
 
1119
  // keep track of the old and new urls so we can substitute them later
1120
- $this->url_remap[ $url ] = $upload['url'];
1121
- $this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
1122
  // keep track of the destination if the remote url is redirected somewhere else
1123
- if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] != $url ) {
1124
- $this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
1125
- }
1126
 
1127
  return $upload;
1128
  }
@@ -1140,12 +1173,10 @@ class TG_WXR_Importer extends WP_Importer {
1140
  // find parents for post orphans
1141
  foreach ( $this->post_orphans as $child_id => $parent_id ) {
1142
  $local_child_id = $local_parent_id = false;
1143
- if ( isset( $this->processed_posts[ $child_id ] ) ) {
1144
- $local_child_id = $this->processed_posts[ $child_id ];
1145
- }
1146
- if ( isset( $this->processed_posts[ $parent_id ] ) ) {
1147
- $local_parent_id = $this->processed_posts[ $parent_id ];
1148
- }
1149
 
1150
  if ( $local_child_id && $local_parent_id ) {
1151
  $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
@@ -1155,23 +1186,19 @@ class TG_WXR_Importer extends WP_Importer {
1155
 
1156
  // all other posts/terms are imported, retry menu items with missing associated object
1157
  $missing_menu_items = $this->missing_menu_items;
1158
- foreach ( $missing_menu_items as $item ) {
1159
  $this->process_menu_item( $item );
1160
- }
1161
 
1162
  // find parents for menu item orphans
1163
  foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
1164
  $local_child_id = $local_parent_id = 0;
1165
- if ( isset( $this->processed_menu_items[ $child_id ] ) ) {
1166
- $local_child_id = $this->processed_menu_items[ $child_id ];
1167
- }
1168
- if ( isset( $this->processed_menu_items[ $parent_id ] ) ) {
1169
- $local_parent_id = $this->processed_menu_items[ $parent_id ];
1170
- }
1171
 
1172
- if ( $local_child_id && $local_parent_id ) {
1173
  update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
1174
- }
1175
  }
1176
  }
1177
 
@@ -1181,13 +1208,13 @@ class TG_WXR_Importer extends WP_Importer {
1181
  function backfill_attachment_urls() {
1182
  global $wpdb;
1183
  // make sure we do the longest urls first, in case one is a substring of another
1184
- uksort( $this->url_remap, array( &$this, 'cmpr_strlen' ) );
1185
 
1186
  foreach ( $this->url_remap as $from_url => $to_url ) {
1187
  // remap urls in post_content
1188
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url ) );
1189
  // remap enclosure urls
1190
- $result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url ) );
1191
  }
1192
  }
1193
 
@@ -1197,12 +1224,11 @@ class TG_WXR_Importer extends WP_Importer {
1197
  function remap_featured_images() {
1198
  // cycle through posts that have a featured image
1199
  foreach ( $this->featured_images as $post_id => $value ) {
1200
- if ( isset( $this->processed_posts[ $value ] ) ) {
1201
- $new_id = $this->processed_posts[ $value ];
1202
  // only update if there's a difference
1203
- if ( $new_id != $value ) {
1204
  update_post_meta( $post_id, '_thumbnail_id', $new_id );
1205
- }
1206
  }
1207
  }
1208
  }
@@ -1223,10 +1249,10 @@ class TG_WXR_Importer extends WP_Importer {
1223
  echo '<div class="wrap">';
1224
  echo '<h2>' . __( 'Import WordPress', 'themegrill-demo-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.', 'themegrill-demo-importer' ), $update->update->new_version );
1232
  echo '</strong></p></div>';
@@ -1243,8 +1269,8 @@ class TG_WXR_Importer 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.', 'themegrill-demo-importer' ) . '</p>';
1247
- echo '<p>' . __( 'Choose a WXR (.xml) file to upload, then click Upload file and import.', 'themegrill-demo-importer' ) . '</p>';
1248
  wp_import_upload_form( 'admin.php?import=wordpress&amp;step=1' );
1249
  echo '</div>';
1250
  }
@@ -1258,9 +1284,8 @@ class TG_WXR_Importer 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
- }
1264
  return $key;
1265
  }
1266
 
@@ -1297,7 +1322,6 @@ class TG_WXR_Importer extends WP_Importer {
1297
 
1298
  /**
1299
  * Added to http_request_timeout filter to force timeout at 60 seconds during import
1300
- *
1301
  * @return int 60
1302
  */
1303
  function bump_request_timeout( $val ) {
@@ -1306,6 +1330,104 @@ class TG_WXR_Importer extends WP_Importer {
1306
 
1307
  // return the difference in length between two strings
1308
  function cmpr_strlen( $a, $b ) {
1309
- return strlen( $b ) - strlen( $a );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
  }
1311
  }
20
  /** Display verbose errors */
21
  define( 'IMPORT_DEBUG', false );
22
 
23
+ /** WXR_Parser_SimpleXML class */
24
+ require dirname( __FILE__ ) . '/class-wxr-parser.php';
25
+
26
+ /** WXR_Parser_SimpleXML class */
27
+ require dirname( __FILE__ ) . '/class-wxr-parser-simplexml.php';
28
+
29
+ /** WXR_Parser_XML class */
30
+ require dirname( __FILE__ ) . '/class-wxr-parser-xml.php';
31
+
32
+ /** WXR_Parser_Regex class */
33
+ require dirname( __FILE__ ) . '/class-wxr-parser-regex.php';
34
 
35
  /**
36
  * TG_WXR_Importer Class.
42
 
43
  // information to import from WXR file
44
  var $version;
45
+ var $authors = array();
46
+ var $posts = array();
47
+ var $terms = array();
48
  var $categories = array();
49
+ var $tags = array();
50
+ var $base_url = '';
51
 
52
  // mappings from old information to new
53
+ var $processed_authors = array();
54
+ var $author_mapping = array();
55
+ var $processed_terms = array();
56
+ var $processed_posts = array();
57
+ var $post_orphans = array();
58
  var $processed_menu_items = array();
59
+ var $menu_item_orphans = array();
60
+ var $missing_menu_items = array();
61
 
62
  var $fetch_attachments = false;
63
+ var $url_remap = array();
64
+ var $featured_images = array();
65
 
66
  /**
67
  * Registered callback function for the WordPress Importer
78
  break;
79
  case 1:
80
  check_admin_referer( 'import-upload' );
81
+ if ( $this->handle_upload() )
82
  $this->import_options();
 
83
  break;
84
  case 2:
85
  check_admin_referer( 'import-wordpress' );
86
  $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() );
87
+ $this->id = (int) $_POST['import_id'];
88
+ $file = get_attached_file( $this->id );
89
+ set_time_limit(0);
90
  $this->import( $file );
91
  break;
92
  }
128
  * @param string $file Path to the WXR file for importing
129
  */
130
  function import_start( $file ) {
131
+ if ( ! is_file($file) ) {
132
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
133
  echo __( 'The file does not exist, please try again.', 'themegrill-demo-importer' ) . '</p>';
134
  $this->footer();
146
 
147
  $this->version = $import_data['version'];
148
  $this->get_authors_from_import( $import_data );
149
+ $this->posts = $import_data['posts'];
150
+ $this->terms = $import_data['terms'];
151
  $this->categories = $import_data['categories'];
152
+ $this->tags = $import_data['tags'];
153
+ $this->base_url = esc_url( $import_data['base_url'] );
154
 
155
  wp_defer_term_counting( true );
156
  wp_defer_comment_counting( true );
192
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
193
  echo esc_html( $file['error'] ) . '</p>';
194
  return false;
195
+ } else if ( ! file_exists( $file['file'] ) ) {
196
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
197
  printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'themegrill-demo-importer' ), esc_html( $file['file'] ) );
198
  echo '</p>';
199
  return false;
200
  }
201
 
202
+ $this->id = (int) $file['id'];
203
  $import_data = $this->parse( $file['file'] );
204
  if ( is_wp_error( $import_data ) ) {
205
  echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themegrill-demo-importer' ) . '</strong><br />';
210
  $this->version = $import_data['version'];
211
  if ( $this->version > $this->max_wxr_version ) {
212
  echo '<div class="error"><p><strong>';
213
+ printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'themegrill-demo-importer' ), esc_html($import_data['version']) );
214
  echo '</strong></p></div>';
215
  }
216
 
230
  function get_authors_from_import( $import_data ) {
231
  if ( ! empty( $import_data['authors'] ) ) {
232
  $this->authors = $import_data['authors'];
233
+ // no author information, grab it from the posts
234
  } else {
235
  foreach ( $import_data['posts'] as $post ) {
236
  $login = sanitize_user( $post['post_author'], true );
240
  continue;
241
  }
242
 
243
+ if ( ! isset($this->authors[$login]) )
244
+ $this->authors[$login] = array(
245
+ 'author_login' => $login,
246
+ 'author_display_name' => $post['post_author']
247
  );
 
248
  }
249
  }
250
  }
255
  */
256
  function import_options() {
257
  $j = 0;
258
+ ?>
259
  <form action="<?php echo admin_url( 'admin.php?import=wordpress&amp;step=2' ); ?>" method="post">
260
+ <?php wp_nonce_field( 'import-wordpress' ); ?>
261
  <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
262
 
263
+ <?php if ( ! empty( $this->authors ) ) : ?>
264
  <h3><?php _e( 'Assign Authors', 'themegrill-demo-importer' ); ?></h3>
265
+ <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.', 'themegrill-demo-importer' ); ?></p>
266
+ <?php if ( $this->allow_create_users() ) : ?>
267
+ <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.', 'themegrill-demo-importer' ), esc_html( get_option('default_role') ) ); ?></p>
268
  <?php endif; ?>
269
  <ol id="authors">
270
+ <?php foreach ( $this->authors as $author ) : ?>
271
  <li><?php $this->author_select( $j++, $author ); ?></li>
272
  <?php endforeach; ?>
273
  </ol>
274
  <?php endif; ?>
275
 
276
+ <?php if ( $this->allow_fetch_attachments() ) : ?>
277
  <h3><?php _e( 'Import Attachments', 'themegrill-demo-importer' ); ?></h3>
278
  <p>
279
  <input type="checkbox" value="1" name="fetch_attachments" id="import-attachments" />
283
 
284
  <p class="submit"><input type="submit" class="button" value="<?php esc_attr_e( 'Submit', 'themegrill-demo-importer' ); ?>" /></p>
285
  </form>
286
+ <?php
287
  }
288
 
289
  /**
290
  * Display import options for an individual author. That is, either create
291
  * a new user based on import info or map to an existing user
292
  *
293
+ * @param int $n Index for each author in the form
294
  * @param array $author Author information, e.g. login, display name, email
295
  */
296
  function author_select( $n, $author ) {
297
  _e( 'Import author:', 'themegrill-demo-importer' );
298
  echo ' <strong>' . esc_html( $author['author_display_name'] );
299
+ if ( $this->version != '1.0' ) echo ' (' . esc_html( $author['author_login'] ) . ')';
 
 
300
  echo '</strong><br />';
301
 
302
+ if ( $this->version != '1.0' )
303
  echo '<div style="margin-left:18px">';
 
304
 
305
  $create_users = $this->allow_create_users();
306
  if ( $create_users ) {
307
+ echo '<label for="user_new_'. $n . '">';
308
  if ( $this->version != '1.0' ) {
309
  _e( 'or create new user with login name:', 'themegrill-demo-importer' );
310
  $value = '';
312
  _e( 'as a new user:', 'themegrill-demo-importer' );
313
  $value = esc_attr( sanitize_user( $author['author_login'], true ) );
314
  }
315
+ echo '</label>';
316
 
317
+ echo ' <input type="text" id="user_new_' . $n . '" name="user_new['.$n.']" value="'. $value .'" /><br />';
318
  }
319
 
320
+ echo '<label for="imported_authors_'. $n . '">';
321
  if ( ! $create_users && $this->version == '1.0' ) {
322
  _e( 'assign posts to an existing user:', 'themegrill-demo-importer' );
323
  } else {
324
  _e( 'or assign posts to an existing user:', 'themegrill-demo-importer' );
325
  }
326
+ echo '</label>';
327
+
328
+ echo ' ' . wp_dropdown_users( array(
329
+ 'name' => "user_map[$n]",
330
+ 'id' => 'imported_authors_' . $n,
331
+ 'multi' => true,
332
+ 'show_option_all' => __( '- Select -', 'themegrill-demo-importer' ),
333
+ 'show' => 'display_name_with_login',
334
+ 'echo' => 0,
335
+ ) );
 
336
 
337
+ echo '<input type="hidden" name="imported_authors['.$n.']" value="' . esc_attr( $author['author_login'] ) . '" />';
338
+
339
+ if ( $this->version != '1.0' )
340
  echo '</div>';
 
341
  }
342
 
343
  /**
346
  * or falls back to the current user in case of error with either of the previous
347
  */
348
  function get_author_mapping() {
349
+ if ( ! isset( $_POST['imported_authors'] ) )
350
  return;
 
351
 
352
  $create_users = $this->allow_create_users();
353
 
354
  foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
355
  // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
356
  $santized_old_login = sanitize_user( $old_login, true );
357
+ $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false;
358
 
359
+ if ( ! empty( $_POST['user_map'][$i] ) ) {
360
+ $user = get_userdata( intval($_POST['user_map'][$i]) );
361
  if ( isset( $user->ID ) ) {
362
+ if ( $old_id )
363
+ $this->processed_authors[$old_id] = $user->ID;
364
+ $this->author_mapping[$santized_old_login] = $user->ID;
 
365
  }
366
+ } else if ( $create_users ) {
367
+ if ( ! empty($_POST['user_new'][$i]) ) {
368
+ $user_id = wp_create_user( $_POST['user_new'][$i], wp_generate_password() );
369
+ } else if ( $this->version != '1.0' ) {
370
  $user_data = array(
371
+ 'user_login' => $old_login,
372
+ 'user_pass' => wp_generate_password(),
373
+ 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '',
374
+ 'display_name' => $this->authors[$old_login]['author_display_name'],
375
+ 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '',
376
+ 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '',
377
  );
378
+ $user_id = wp_insert_user( $user_data );
379
  }
380
 
381
  if ( ! is_wp_error( $user_id ) ) {
382
+ if ( $old_id )
383
+ $this->processed_authors[$old_id] = $user_id;
384
+ $this->author_mapping[$santized_old_login] = $user_id;
 
385
  } else {
386
+ printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'themegrill-demo-importer' ), esc_html($this->authors[$old_login]['author_display_name']) );
387
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
388
  echo ' ' . $user_id->get_error_message();
 
389
  echo '<br />';
390
  }
391
  }
392
 
393
  // failsafe: if the user_id was invalid, default to the current user
394
+ if ( ! isset( $this->author_mapping[$santized_old_login] ) ) {
395
+ if ( $old_id )
396
+ $this->processed_authors[$old_id] = (int) get_current_user_id();
397
+ $this->author_mapping[$santized_old_login] = (int) get_current_user_id();
 
398
  }
399
  }
400
  }
407
  function process_categories() {
408
  $this->categories = apply_filters( 'wp_import_categories', $this->categories );
409
 
410
+ if ( empty( $this->categories ) )
411
  return;
 
412
 
413
  foreach ( $this->categories as $cat ) {
414
  // if the category already exists leave it alone
415
  $term_id = term_exists( $cat['category_nicename'], 'category' );
416
  if ( $term_id ) {
417
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
418
+ if ( isset($cat['term_id']) )
419
+ $this->processed_terms[intval($cat['term_id'])] = (int) $term_id;
 
 
 
420
  continue;
421
  }
422
 
423
+ $parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] );
424
+ $description = isset( $cat['category_description'] ) ? $cat['category_description'] : '';
425
+
426
+ $data = array(
427
  'category_nicename' => $cat['category_nicename'],
428
+ 'category_parent' => $parent,
429
+ 'cat_name' => wp_slash( $cat['cat_name'] ),
430
+ 'category_description' => wp_slash( $description ),
431
  );
 
432
 
433
+ $id = wp_insert_category( $data );
434
+ if ( ! is_wp_error( $id ) && $id > 0 ) {
435
+ if ( isset($cat['term_id']) )
436
+ $this->processed_terms[intval($cat['term_id'])] = $id;
 
437
  } else {
438
+ printf( __( 'Failed to import category %s', 'themegrill-demo-importer' ), esc_html($cat['category_nicename']) );
439
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
440
  echo ': ' . $id->get_error_message();
 
441
  echo '<br />';
442
  continue;
443
  }
444
 
445
+ $this->process_termmeta( $cat, $id );
446
  }
447
 
448
  unset( $this->categories );
456
  function process_tags() {
457
  $this->tags = apply_filters( 'wp_import_tags', $this->tags );
458
 
459
+ if ( empty( $this->tags ) )
460
  return;
 
461
 
462
  foreach ( $this->tags as $tag ) {
463
  // if the tag already exists leave it alone
464
  $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
465
  if ( $term_id ) {
466
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
467
+ if ( isset($tag['term_id']) )
468
+ $this->processed_terms[intval($tag['term_id'])] = (int) $term_id;
 
 
 
469
  continue;
470
  }
471
 
472
+ $description = isset( $tag['tag_description'] ) ? $tag['tag_description'] : '';
473
+ $args = array(
 
474
  'slug' => $tag['tag_slug'],
475
+ 'description' => wp_slash( $description ),
476
  );
477
 
478
+ $id = wp_insert_term( wp_slash( $tag['tag_name'] ), 'post_tag', $args );
479
  if ( ! is_wp_error( $id ) ) {
480
+ if ( isset($tag['term_id']) )
481
+ $this->processed_terms[intval($tag['term_id'])] = $id['term_id'];
 
482
  } else {
483
+ printf( __( 'Failed to import post tag %s', 'themegrill-demo-importer' ), esc_html($tag['tag_name']) );
484
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
485
  echo ': ' . $id->get_error_message();
 
486
  echo '<br />';
487
  continue;
488
  }
501
  function process_terms() {
502
  $this->terms = apply_filters( 'wp_import_terms', $this->terms );
503
 
504
+ if ( empty( $this->terms ) )
505
  return;
 
506
 
507
  foreach ( $this->terms as $term ) {
508
  // if the term already exists in the correct taxonomy leave it alone
509
  $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
510
  if ( $term_id ) {
511
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
512
+ if ( isset($term['term_id']) )
513
+ $this->processed_terms[intval($term['term_id'])] = (int) $term_id;
 
 
 
514
  continue;
515
  }
516
 
522
  $parent = $parent['term_id'];
523
  }
524
  }
525
+
526
  $description = isset( $term['term_description'] ) ? $term['term_description'] : '';
527
+ $args = array(
528
  'slug' => $term['slug'],
529
+ 'description' => wp_slash( $description ),
530
+ 'parent' => (int) $parent
531
  );
532
 
533
+ $id = wp_insert_term( wp_slash( $term['term_name'] ), $term['term_taxonomy'], $args );
534
  if ( ! is_wp_error( $id ) ) {
535
+ if ( isset($term['term_id']) )
536
+ $this->processed_terms[intval($term['term_id'])] = $id['term_id'];
 
537
  } else {
538
+ printf( __( 'Failed to import %s %s', 'themegrill-demo-importer' ), esc_html($term['term_taxonomy']), esc_html($term['term_name']) );
539
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
540
  echo ': ' . $id->get_error_message();
 
541
  echo '<br />';
542
  continue;
543
  }
557
  * @param int $term_id ID of the newly created term.
558
  */
559
  protected function process_termmeta( $term, $term_id ) {
560
+ if ( ! function_exists( 'add_term_meta' ) ) {
561
+ return;
562
+ }
563
+
564
  if ( ! isset( $term['termmeta'] ) ) {
565
  $term['termmeta'] = array();
566
  }
598
  // Export gets meta straight from the DB so could have a serialized string
599
  $value = maybe_unserialize( $meta['value'] );
600
 
601
+ add_term_meta( $term_id, wp_slash( $key ), wp_slash_strings_only( $value ) );
602
 
603
  /**
604
  * Fires after term meta is imported.
628
  $post = apply_filters( 'wp_import_post_data_raw', $post );
629
 
630
  if ( ! post_type_exists( $post['post_type'] ) ) {
631
+ printf( __( 'Failed to import &#8220;%s&#8221;: Invalid post type %s', 'themegrill-demo-importer' ),
632
+ esc_html($post['post_title']), esc_html($post['post_type']) );
 
 
 
633
  echo '<br />';
634
  do_action( 'wp_import_post_exists', $post );
635
  continue;
636
  }
637
 
638
+ if ( isset( $this->processed_posts[$post['post_id']] ) && ! empty( $post['post_id'] ) )
639
  continue;
 
640
 
641
+ if ( $post['status'] == 'auto-draft' )
642
  continue;
 
643
 
644
  if ( 'nav_menu_item' == $post['post_type'] ) {
645
  $this->process_menu_item( $post );
665
  $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
666
 
667
  if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
668
+ printf( __('%s &#8220;%s&#8221; already exists.', 'themegrill-demo-importer'), $post_type_object->labels->singular_name, esc_html($post['post_title']) );
669
  echo '<br />';
670
+ $comment_post_ID = $post_id = $post_exists;
671
  $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
672
  } else {
673
  $post_parent = (int) $post['post_parent'];
674
  if ( $post_parent ) {
675
  // if we already know the parent, map it to the new local ID
676
+ if ( isset( $this->processed_posts[$post_parent] ) ) {
677
+ $post_parent = $this->processed_posts[$post_parent];
678
+ // otherwise record the parent for later
679
  } else {
680
+ $this->post_orphans[intval($post['post_id'])] = $post_parent;
681
+ $post_parent = 0;
682
  }
683
  }
684
 
685
  // map the post author
686
  $author = sanitize_user( $post['post_author'], true );
687
+ if ( isset( $this->author_mapping[$author] ) )
688
+ $author = $this->author_mapping[$author];
689
+ else
690
  $author = (int) get_current_user_id();
 
691
 
692
  $postdata = array(
693
+ 'import_id' => $post['post_id'], 'post_author' => $author, 'post_date' => $post['post_date'],
694
+ 'post_date_gmt' => $post['post_date_gmt'], 'post_content' => $post['post_content'],
695
+ 'post_excerpt' => $post['post_excerpt'], 'post_title' => $post['post_title'],
696
+ 'post_status' => $post['status'], 'post_name' => $post['post_name'],
697
+ 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'],
698
+ 'guid' => $post['guid'], 'post_parent' => $post_parent, 'menu_order' => $post['menu_order'],
699
+ 'post_type' => $post['post_type'], 'post_password' => $post['post_password']
 
 
 
 
 
 
 
 
 
700
  );
701
 
702
  $original_post_ID = $post['post_id'];
703
+ $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
704
 
705
  $postdata = wp_slash( $postdata );
706
 
707
  if ( 'attachment' == $postdata['post_type'] ) {
708
+ $remote_url = ! empty($post['attachment_url']) ? $post['attachment_url'] : $post['guid'];
709
 
710
  // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
711
  // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
712
  $postdata['upload_date'] = $post['post_date'];
713
  if ( isset( $post['postmeta'] ) ) {
714
+ foreach( $post['postmeta'] as $meta ) {
715
  if ( $meta['key'] == '_wp_attached_file' ) {
716
+ if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) )
717
  $postdata['upload_date'] = $matches[0];
 
718
  break;
719
  }
720
  }
727
  }
728
 
729
  if ( is_wp_error( $post_id ) ) {
730
+ printf( __( 'Failed to import %s &#8220;%s&#8221;', 'themegrill-demo-importer' ),
731
+ $post_type_object->labels->singular_name, esc_html($post['post_title']) );
732
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
 
 
 
733
  echo ': ' . $post_id->get_error_message();
 
734
  echo '<br />';
735
  continue;
736
  }
737
 
738
+ if ( $post['is_sticky'] == 1 )
739
  stick_post( $post_id );
 
740
  }
741
 
742
  // map pre-import ID to local ID
743
+ $this->processed_posts[intval($post['post_id'])] = (int) $post_id;
744
 
745
+ if ( ! isset( $post['terms'] ) )
746
  $post['terms'] = array();
 
747
 
748
  $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
749
 
752
  $terms_to_set = array();
753
  foreach ( $post['terms'] as $term ) {
754
  // back compat with WXR 1.0 map 'tag' to 'post_tag'
755
+ $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
756
  $term_exists = term_exists( $term['slug'], $taxonomy );
757
+ $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
758
  if ( ! $term_id ) {
759
  $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
760
  if ( ! is_wp_error( $t ) ) {
761
  $term_id = $t['term_id'];
762
  do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
763
  } else {
764
+ printf( __( 'Failed to import %s %s', 'themegrill-demo-importer' ), esc_html($taxonomy), esc_html($term['name']) );
765
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
766
  echo ': ' . $t->get_error_message();
 
767
  echo '<br />';
768
  do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
769
  continue;
770
  }
771
  }
772
+ $terms_to_set[$taxonomy][] = intval( $term_id );
773
  }
774
 
775
  foreach ( $terms_to_set as $tax => $ids ) {
779
  unset( $post['terms'], $terms_to_set );
780
  }
781
 
782
+ if ( ! isset( $post['comments'] ) )
783
  $post['comments'] = array();
 
784
 
785
  $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
786
 
787
  // add/update comments
788
  if ( ! empty( $post['comments'] ) ) {
789
+ $num_comments = 0;
790
  $inserted_comments = array();
791
  foreach ( $post['comments'] as $comment ) {
792
+ $comment_id = $comment['comment_id'];
793
+ $newcomments[$comment_id]['comment_post_ID'] = $comment_post_ID;
794
+ $newcomments[$comment_id]['comment_author'] = $comment['comment_author'];
795
+ $newcomments[$comment_id]['comment_author_email'] = $comment['comment_author_email'];
796
+ $newcomments[$comment_id]['comment_author_IP'] = $comment['comment_author_IP'];
797
+ $newcomments[$comment_id]['comment_author_url'] = $comment['comment_author_url'];
798
+ $newcomments[$comment_id]['comment_date'] = $comment['comment_date'];
799
+ $newcomments[$comment_id]['comment_date_gmt'] = $comment['comment_date_gmt'];
800
+ $newcomments[$comment_id]['comment_content'] = $comment['comment_content'];
801
+ $newcomments[$comment_id]['comment_approved'] = $comment['comment_approved'];
802
+ $newcomments[$comment_id]['comment_type'] = $comment['comment_type'];
803
+ $newcomments[$comment_id]['comment_parent'] = $comment['comment_parent'];
804
+ $newcomments[$comment_id]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
805
+ if ( isset( $this->processed_authors[$comment['comment_user_id']] ) )
806
+ $newcomments[$comment_id]['user_id'] = $this->processed_authors[$comment['comment_user_id']];
 
807
  }
808
  ksort( $newcomments );
809
 
810
  foreach ( $newcomments as $key => $comment ) {
811
  // if this is a new post we can skip the comment_exists() check
812
  if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
813
+ if ( isset( $inserted_comments[$comment['comment_parent']] ) ) {
814
  $comment['comment_parent'] = $inserted_comments[ $comment['comment_parent'] ];
815
  }
816
+
817
+ $comment_data = wp_slash( $comment );
818
+ unset( $comment_data['commentmeta'] ); // Handled separately, wp_insert_comment() also expects `comment_meta`.
819
+ $comment_data = wp_filter_comment( $comment_data );
820
+
821
+ $inserted_comments[ $key ] = wp_insert_comment( $comment_data );
822
+
823
  do_action( 'wp_import_insert_comment', $inserted_comments[ $key ], $comment, $comment_post_ID, $post );
824
 
825
+ foreach( $comment['commentmeta'] as $meta ) {
826
  $value = maybe_unserialize( $meta['value'] );
827
+
828
+ add_comment_meta( $inserted_comments[ $key ], wp_slash( $meta['key'] ), wp_slash_strings_only( $value ) );
829
  }
830
 
831
  $num_comments++;
834
  unset( $newcomments, $inserted_comments, $post['comments'] );
835
  }
836
 
837
+ if ( ! isset( $post['postmeta'] ) )
838
  $post['postmeta'] = array();
 
839
 
840
  $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
841
 
842
  // add/update post meta
843
  if ( ! empty( $post['postmeta'] ) ) {
844
  foreach ( $post['postmeta'] as $meta ) {
845
+ $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
846
  $value = false;
847
 
848
  if ( '_edit_last' == $key ) {
849
+ if ( isset( $this->processed_authors[intval($meta['value'])] ) )
850
+ $value = $this->processed_authors[intval($meta['value'])];
851
+ else
852
  $key = false;
 
853
  }
854
 
855
  if ( $key ) {
858
  $value = maybe_unserialize( $meta['value'] );
859
  }
860
 
861
+ add_post_meta( $post_id, wp_slash( $key ), wp_slash_strings_only( $value ) );
862
+
863
  do_action( 'import_post_meta', $post_id, $key, $value );
864
 
865
  // if the post has a featured image, take note of this in case of remap
866
+ if ( '_thumbnail_id' == $key )
867
+ $this->featured_images[$post_id] = (int) $value;
 
868
  }
869
  }
870
  }
885
  */
886
  function process_menu_item( $item ) {
887
  // skip draft, orphaned menu items
888
+ if ( 'draft' == $item['status'] )
889
  return;
 
890
 
891
  $menu_slug = false;
892
+ if ( isset($item['terms']) ) {
893
  // loop through terms, assume first nav_menu term is correct menu
894
  foreach ( $item['terms'] as $term ) {
895
  if ( 'nav_menu' == $term['domain'] ) {
915
  $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
916
  }
917
 
918
+ foreach ( $item['postmeta'] as $meta )
919
+ ${$meta['key']} = $meta['value'];
 
 
 
 
 
920
 
921
+ if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[intval($_menu_item_object_id)] ) ) {
922
+ $_menu_item_object_id = $this->processed_terms[intval($_menu_item_object_id)];
923
+ } else if ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[intval($_menu_item_object_id)] ) ) {
924
+ $_menu_item_object_id = $this->processed_posts[intval($_menu_item_object_id)];
925
+ } else if ( 'custom' != $_menu_item_type ) {
926
  // associated object is missing or not imported yet, we'll retry later
927
  $this->missing_menu_items[] = $item;
928
  return;
929
  }
930
 
931
+ if ( isset( $this->processed_menu_items[intval($_menu_item_menu_item_parent)] ) ) {
932
+ $_menu_item_menu_item_parent = $this->processed_menu_items[intval($_menu_item_menu_item_parent)];
933
+ } else if ( $_menu_item_menu_item_parent ) {
934
+ $this->menu_item_orphans[intval($item['post_id'])] = (int) $_menu_item_menu_item_parent;
935
+ $_menu_item_menu_item_parent = 0;
936
  }
937
 
938
  // wp_update_nav_menu_item expects CSS classes as a space separated string
939
  $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
940
+ if ( is_array( $_menu_item_classes ) )
941
  $_menu_item_classes = implode( ' ', $_menu_item_classes );
 
942
 
943
  $args = array(
944
+ 'menu-item-object-id' => $_menu_item_object_id,
945
+ 'menu-item-object' => $_menu_item_object,
946
+ 'menu-item-parent-id' => $_menu_item_menu_item_parent,
947
+ 'menu-item-position' => intval( $item['menu_order'] ),
948
+ 'menu-item-type' => $_menu_item_type,
949
+ 'menu-item-title' => $item['post_title'],
950
+ 'menu-item-url' => $_menu_item_url,
951
  'menu-item-description' => $item['post_content'],
952
+ 'menu-item-attr-title' => $item['post_excerpt'],
953
+ 'menu-item-target' => $_menu_item_target,
954
+ 'menu-item-classes' => $_menu_item_classes,
955
+ 'menu-item-xfn' => $_menu_item_xfn,
956
+ 'menu-item-status' => $item['status']
957
  );
958
 
959
  $id = wp_update_nav_menu_item( $menu_id, 0, $args );
960
+ if ( $id && ! is_wp_error( $id ) )
961
+ $this->processed_menu_items[intval($item['post_id'])] = (int) $id;
 
962
  }
963
 
964
  /**
965
  * If fetching attachments is enabled then attempt to create a new attachment
966
  *
967
+ * @param array $post Attachment post details from WXR
968
  * @param string $url URL to fetch attachment from
969
  * @return int|WP_Error Post ID on success, WP_Error otherwise
970
  */
971
  function process_attachment( $post, $url ) {
972
+ if ( ! $this->fetch_attachments )
973
+ return new WP_Error( 'attachment_processing_error',
974
+ __( 'Fetching attachments is not enabled', 'themegrill-demo-importer' ) );
 
 
 
975
 
976
  // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
977
+ if ( preg_match( '|^/[\w\W]+$|', $url ) )
978
  $url = rtrim( $this->base_url, '/' ) . $url;
 
979
 
980
  $upload = $this->fetch_remote_file( $url, $post );
981
+ if ( is_wp_error( $upload ) )
982
  return $upload;
 
983
 
984
+ if ( $info = wp_check_filetype( $upload['file'] ) )
985
  $post['post_mime_type'] = $info['type'];
986
+ else
987
+ return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'themegrill-demo-importer') );
 
988
 
989
  $post['guid'] = $upload['url'];
990
 
995
  // remap resized image URLs, works by stripping the extension and remapping the URL stub.
996
  if ( preg_match( '!^image/!', $info['type'] ) ) {
997
  $parts = pathinfo( $url );
998
+ $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
999
 
1000
  $parts_new = pathinfo( $upload['url'] );
1001
+ $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
1002
 
1003
+ $this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
1004
  }
1005
 
1006
  return $post_id;
1010
  * Attempt to download a remote file attachment
1011
  *
1012
  * @param string $url URL of item to fetch
1013
+ * @param array $post Attachment details
1014
  * @return array|WP_Error Local file location details on success, WP_Error otherwise
1015
  */
1016
  function fetch_remote_file( $url, $post ) {
1017
+ // Extract the file name from the URL.
1018
+ $file_name = basename( parse_url( $url, PHP_URL_PATH ) );
1019
 
1020
+ if ( ! $file_name ) {
1021
+ $file_name = md5( $url );
 
 
1022
  }
1023
 
1024
+ $tmp_file_name = wp_tempnam( $file_name );
1025
+ if ( ! $tmp_file_name ) {
1026
+ return new WP_Error( 'import_no_file', __( 'Could not create temporary file.', 'themegrill-demo-importer' ) );
1027
+ }
 
 
 
 
 
1028
 
1029
+ // Fetch the remote URL and write it to the placeholder file.
1030
+ $remote_response = wp_safe_remote_get( $url, array(
1031
+ 'timeout' => 300,
1032
+ 'stream' => true,
1033
+ 'filename' => $tmp_file_name,
1034
+ 'headers' => array(
1035
+ 'Accept-Encoding' => 'identity',
1036
+ ),
1037
+ ) );
1038
+
1039
+ if ( is_wp_error( $remote_response ) ) {
1040
+ @unlink( $tmp_file_name );
1041
+ return new WP_Error(
1042
+ 'import_file_error',
1043
+ sprintf(
1044
+ /* translators: 1: The WordPress error message. 2: The WordPress error code. */
1045
+ __( 'Request failed due to an error: %1$s (%2$s)', 'themegrill-demo-importer' ),
1046
+ esc_html( $remote_response->get_error_message() ),
1047
+ esc_html( $remote_response->get_error_code() )
1048
+ )
1049
+ );
1050
+ }
1051
 
1052
+ $remote_response_code = (int) wp_remote_retrieve_response_code( $remote_response );
1053
+
1054
+ // Make sure the fetch was successful.
1055
+ if ( 200 !== $remote_response_code ) {
1056
+ @unlink( $tmp_file_name );
1057
+ return new WP_Error(
1058
+ 'import_file_error',
1059
+ sprintf(
1060
+ /* translators: 1: The HTTP error message. 2: The HTTP error code. */
1061
+ __( 'Remote server returned the following unexpected result: %1$s (%2$s)', 'themegrill-demo-importer' ),
1062
+ get_status_header_desc( $remote_response_code ),
1063
+ esc_html( $remote_response_code )
1064
+ )
1065
+ );
1066
  }
1067
 
1068
+ $headers = wp_remote_retrieve_headers( $remote_response );
1069
 
1070
+ // Request failed.
1071
+ if ( ! $headers ) {
1072
+ @unlink( $tmp_file_name );
1073
+ return new WP_Error( 'import_file_error', __('Remote server did not respond', 'themegrill-demo-importer') );
1074
  }
1075
 
1076
+ $filesize = (int) filesize( $tmp_file_name );
1077
 
1078
+ if ( 0 === $filesize ) {
1079
+ @unlink( $tmp_file_name );
1080
+ return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'themegrill-demo-importer') );
1081
  }
1082
 
1083
+ if ( ! isset( $headers['content-encoding'] ) && isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
1084
+ @unlink( $tmp_file_name );
1085
+ return new WP_Error( 'import_file_error', __('Downloaded file has incorrect size', 'themegrill-demo-importer' ) );
1086
  }
1087
 
1088
  $max_size = (int) $this->max_attachment_size();
1089
  if ( ! empty( $max_size ) && $filesize > $max_size ) {
1090
+ @unlink( $tmp_file_name );
1091
+ return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'themegrill-demo-importer' ), size_format($max_size) ) );
1092
+ }
1093
+
1094
+ // Override file name with Content-Disposition header value.
1095
+ if ( ! empty( $headers['content-disposition'] ) ) {
1096
+ $file_name_from_disposition = self::get_filename_from_disposition( (array) $headers['content-disposition'] );
1097
+ if ( $file_name_from_disposition ) {
1098
+ $file_name = $file_name_from_disposition;
1099
+ }
1100
+ }
1101
+
1102
+ // Set file extension if missing.
1103
+ $file_ext = pathinfo( $file_name, PATHINFO_EXTENSION );
1104
+ if ( ! $file_ext && ! empty( $headers['content-type'] ) ) {
1105
+ $extension = self::get_file_extension_by_mime_type( $headers['content-type'] );
1106
+ if ( $extension ) {
1107
+ $file_name = "{$file_name}.{$extension}";
1108
+ }
1109
+ }
1110
+
1111
+ // Handle the upload like _wp_handle_upload() does.
1112
+ $wp_filetype = wp_check_filetype_and_ext( $tmp_file_name, $file_name );
1113
+ $ext = empty( $wp_filetype['ext'] ) ? '' : $wp_filetype['ext'];
1114
+ $type = empty( $wp_filetype['type'] ) ? '' : $wp_filetype['type'];
1115
+ $proper_filename = empty( $wp_filetype['proper_filename'] ) ? '' : $wp_filetype['proper_filename'];
1116
+
1117
+ // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect.
1118
+ if ( $proper_filename ) {
1119
+ $file_name = $proper_filename;
1120
+ }
1121
+
1122
+ if ( ( ! $type || ! $ext ) && ! current_user_can( 'unfiltered_upload' ) ) {
1123
+ return new WP_Error( 'import_file_error', __( 'Sorry, this file type is not permitted for security reasons.', 'themegrill-demo-importer' ) );
1124
+ }
1125
+
1126
+ $uploads = wp_upload_dir( $post['upload_date'] );
1127
+ if ( ! ( $uploads && false === $uploads['error'] ) ) {
1128
+ return new WP_Error( 'upload_dir_error', $uploads['error'] );
1129
+ }
1130
+
1131
+ // Move the file to the uploads dir.
1132
+ $file_name = wp_unique_filename( $uploads['path'], $file_name );
1133
+ $new_file = $uploads['path'] . "/$file_name";
1134
+ $move_new_file = copy( $tmp_file_name, $new_file );
1135
+
1136
+ if ( ! $move_new_file ) {
1137
+ @unlink( $tmp_file_name );
1138
+ return new WP_Error( 'import_file_error', __( 'The uploaded file could not be moved', 'themegrill-demo-importer' ) );
1139
  }
1140
 
1141
+ // Set correct file permissions.
1142
+ $stat = stat( dirname( $new_file ) );
1143
+ $perms = $stat['mode'] & 0000666;
1144
+ chmod( $new_file, $perms );
1145
+
1146
+ $upload = array(
1147
+ 'file' => $new_file,
1148
+ 'url' => $uploads['url'] . "/$file_name",
1149
+ 'type' => $wp_filetype['type'],
1150
+ 'error' => false,
1151
+ );
1152
+
1153
  // keep track of the old and new urls so we can substitute them later
1154
+ $this->url_remap[$url] = $upload['url'];
1155
+ $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed?
1156
  // keep track of the destination if the remote url is redirected somewhere else
1157
+ if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url )
1158
+ $this->url_remap[$headers['x-final-location']] = $upload['url'];
 
1159
 
1160
  return $upload;
1161
  }
1173
  // find parents for post orphans
1174
  foreach ( $this->post_orphans as $child_id => $parent_id ) {
1175
  $local_child_id = $local_parent_id = false;
1176
+ if ( isset( $this->processed_posts[$child_id] ) )
1177
+ $local_child_id = $this->processed_posts[$child_id];
1178
+ if ( isset( $this->processed_posts[$parent_id] ) )
1179
+ $local_parent_id = $this->processed_posts[$parent_id];
 
 
1180
 
1181
  if ( $local_child_id && $local_parent_id ) {
1182
  $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
1186
 
1187
  // all other posts/terms are imported, retry menu items with missing associated object
1188
  $missing_menu_items = $this->missing_menu_items;
1189
+ foreach ( $missing_menu_items as $item )
1190
  $this->process_menu_item( $item );
 
1191
 
1192
  // find parents for menu item orphans
1193
  foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
1194
  $local_child_id = $local_parent_id = 0;
1195
+ if ( isset( $this->processed_menu_items[$child_id] ) )
1196
+ $local_child_id = $this->processed_menu_items[$child_id];
1197
+ if ( isset( $this->processed_menu_items[$parent_id] ) )
1198
+ $local_parent_id = $this->processed_menu_items[$parent_id];
 
 
1199
 
1200
+ if ( $local_child_id && $local_parent_id )
1201
  update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
 
1202
  }
1203
  }
1204
 
1208
  function backfill_attachment_urls() {
1209
  global $wpdb;
1210
  // make sure we do the longest urls first, in case one is a substring of another
1211
+ uksort( $this->url_remap, array(&$this, 'cmpr_strlen') );
1212
 
1213
  foreach ( $this->url_remap as $from_url => $to_url ) {
1214
  // remap urls in post_content
1215
+ $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );
1216
  // remap enclosure urls
1217
+ $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) );
1218
  }
1219
  }
1220
 
1224
  function remap_featured_images() {
1225
  // cycle through posts that have a featured image
1226
  foreach ( $this->featured_images as $post_id => $value ) {
1227
+ if ( isset( $this->processed_posts[$value] ) ) {
1228
+ $new_id = $this->processed_posts[$value];
1229
  // only update if there's a difference
1230
+ if ( $new_id != $value )
1231
  update_post_meta( $post_id, '_thumbnail_id', $new_id );
 
1232
  }
1233
  }
1234
  }
1249
  echo '<div class="wrap">';
1250
  echo '<h2>' . __( 'Import WordPress', 'themegrill-demo-importer' ) . '</h2>';
1251
 
1252
+ $updates = get_plugin_updates();
1253
+ $basename = plugin_basename(__FILE__);
1254
+ if ( isset( $updates[$basename] ) ) {
1255
+ $update = $updates[$basename];
1256
  echo '<div class="error"><p><strong>';
1257
  printf( __( 'A new version of this importer is available. Please update to version %s to ensure compatibility with newer export files.', 'themegrill-demo-importer' ), $update->update->new_version );
1258
  echo '</strong></p></div>';
1269
  */
1270
  function greet() {
1271
  echo '<div class="narrow">';
1272
+ 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.', 'themegrill-demo-importer' ).'</p>';
1273
+ echo '<p>'.__( 'Choose a WXR (.xml) file to upload, then click Upload file and import.', 'themegrill-demo-importer' ).'</p>';
1274
  wp_import_upload_form( 'admin.php?import=wordpress&amp;step=1' );
1275
  echo '</div>';
1276
  }
1284
  function is_valid_meta_key( $key ) {
1285
  // skip attachment metadata since we'll regenerate it from scratch
1286
  // skip _edit_lock as not relevant for import
1287
+ if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) )
1288
  return false;
 
1289
  return $key;
1290
  }
1291
 
1322
 
1323
  /**
1324
  * Added to http_request_timeout filter to force timeout at 60 seconds during import
 
1325
  * @return int 60
1326
  */
1327
  function bump_request_timeout( $val ) {
1330
 
1331
  // return the difference in length between two strings
1332
  function cmpr_strlen( $a, $b ) {
1333
+ return strlen($b) - strlen($a);
1334
+ }
1335
+
1336
+ /**
1337
+ * Parses filename from a Content-Disposition header value.
1338
+ *
1339
+ * As per RFC6266:
1340
+ *
1341
+ * content-disposition = "Content-Disposition" ":"
1342
+ * disposition-type *( ";" disposition-parm )
1343
+ *
1344
+ * disposition-type = "inline" | "attachment" | disp-ext-type
1345
+ * ; case-insensitive
1346
+ * disp-ext-type = token
1347
+ *
1348
+ * disposition-parm = filename-parm | disp-ext-parm
1349
+ *
1350
+ * filename-parm = "filename" "=" value
1351
+ * | "filename*" "=" ext-value
1352
+ *
1353
+ * disp-ext-parm = token "=" value
1354
+ * | ext-token "=" ext-value
1355
+ * ext-token = <the characters in token, followed by "*">
1356
+ *
1357
+ * @since 0.7.0
1358
+ *
1359
+ * @see WP_REST_Attachments_Controller::get_filename_from_disposition()
1360
+ *
1361
+ * @link http://tools.ietf.org/html/rfc2388
1362
+ * @link http://tools.ietf.org/html/rfc6266
1363
+ *
1364
+ * @param string[] $disposition_header List of Content-Disposition header values.
1365
+ * @return string|null Filename if available, or null if not found.
1366
+ */
1367
+ protected static function get_filename_from_disposition( $disposition_header ) {
1368
+ // Get the filename.
1369
+ $filename = null;
1370
+
1371
+ foreach ( $disposition_header as $value ) {
1372
+ $value = trim( $value );
1373
+
1374
+ if ( strpos( $value, ';' ) === false ) {
1375
+ continue;
1376
+ }
1377
+
1378
+ list( $type, $attr_parts ) = explode( ';', $value, 2 );
1379
+
1380
+ $attr_parts = explode( ';', $attr_parts );
1381
+ $attributes = array();
1382
+
1383
+ foreach ( $attr_parts as $part ) {
1384
+ if ( strpos( $part, '=' ) === false ) {
1385
+ continue;
1386
+ }
1387
+
1388
+ list( $key, $value ) = explode( '=', $part, 2 );
1389
+
1390
+ $attributes[ trim( $key ) ] = trim( $value );
1391
+ }
1392
+
1393
+ if ( empty( $attributes['filename'] ) ) {
1394
+ continue;
1395
+ }
1396
+
1397
+ $filename = trim( $attributes['filename'] );
1398
+
1399
+ // Unquote quoted filename, but after trimming.
1400
+ if ( substr( $filename, 0, 1 ) === '"' && substr( $filename, -1, 1 ) === '"' ) {
1401
+ $filename = substr( $filename, 1, -1 );
1402
+ }
1403
+ }
1404
+
1405
+ return $filename;
1406
+ }
1407
+
1408
+ /**
1409
+ * Retrieves file extension by mime type.
1410
+ *
1411
+ * @since 0.7.0
1412
+ *
1413
+ * @param string $mime_type Mime type to search extension for.
1414
+ * @return string|null File extension if available, or null if not found.
1415
+ */
1416
+ protected static function get_file_extension_by_mime_type( $mime_type ) {
1417
+ static $map = null;
1418
+
1419
+ if ( is_array( $map ) ) {
1420
+ return isset( $map[ $mime_type ] ) ? $map[ $mime_type ] : null;
1421
+ }
1422
+
1423
+ $mime_types = wp_get_mime_types();
1424
+ $map = array_flip( $mime_types );
1425
+
1426
+ // Some types have multiple extensions, use only the first one.
1427
+ foreach ( $map as $type => $extensions ) {
1428
+ $map[ $type ] = strtok( $extensions, '|' );
1429
+ }
1430
+
1431
+ return isset( $map[ $mime_type ] ) ? $map[ $mime_type ] : null;
1432
  }
1433
  }
includes/importers/wordpress-importer/class-wxr-parser-regex.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress eXtended RSS file parser implementations
4
+ *
5
+ * @package WordPress
6
+ * @subpackage Importer
7
+ */
8
+
9
+ /**
10
+ * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
11
+ */
12
+ class TG_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
+
30
+ $multiline_tags = array(
31
+ 'item' => array( 'posts', array( $this, 'process_post' ) ),
32
+ 'wp:category' => array( 'categories', array( $this, 'process_category' ) ),
33
+ 'wp:tag' => array( 'tags', array( $this, 'process_tag' ) ),
34
+ 'wp:term' => array( 'terms', array( $this, 'process_term' ) ),
35
+ );
36
+
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 );
47
+ $this->base_url = $url[1];
48
+ continue;
49
+ }
50
+
51
+ if ( false !== strpos( $importline, '<wp:base_blog_url>' ) ) {
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', 'themegrill-demo-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
+
110
+ function get_tag( $string, $tag ) {
111
+ preg_match( "|<$tag.*?>(.*?)</$tag>|is", $string, $return );
112
+ if ( isset( $return[1] ) ) {
113
+ if ( substr( $return[1], 0, 9 ) == '<![CDATA[' ) {
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
+ }
122
+ } else {
123
+ $return = $return[1];
124
+ }
125
+ } else {
126
+ $return = '';
127
+ }
128
+ return $return;
129
+ }
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
+
140
+ $term_meta = $this->process_meta( $c, 'wp:termmeta' );
141
+ if ( ! empty( $term_meta ) ) {
142
+ $term['termmeta'] = $term_meta;
143
+ }
144
+
145
+ return $term;
146
+ }
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
+
156
+ $term_meta = $this->process_meta( $t, 'wp:termmeta' );
157
+ if ( ! empty( $term_meta ) ) {
158
+ $term['termmeta'] = $term_meta;
159
+ }
160
+
161
+ return $term;
162
+ }
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
+
174
+ $term_meta = $this->process_meta( $t, 'wp:termmeta' );
175
+ if ( ! empty( $term_meta ) ) {
176
+ $term['termmeta'] = $term_meta;
177
+ }
178
+
179
+ return $term;
180
+ }
181
+
182
+ function process_meta( $string, $tag ) {
183
+ $parsed_meta = array();
184
+
185
+ preg_match_all( "|<$tag>(.+?)</$tag>|is", $string, $meta );
186
+
187
+ if ( ! isset( $meta[1] ) ) {
188
+ return $parsed_meta;
189
+ }
190
+
191
+ foreach ( $meta[1] as $m ) {
192
+ $parsed_meta[] = array(
193
+ 'key' => $this->get_tag( $m, 'wp:meta_key' ),
194
+ 'value' => $this->get_tag( $m, 'wp:meta_value' ),
195
+ );
196
+ }
197
+
198
+ return $parsed_meta;
199
+ }
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
+
212
+ function process_post( $post ) {
213
+ $post_id = $this->get_tag( $post, 'wp:post_id' );
214
+ $post_title = $this->get_tag( $post, 'title' );
215
+ $post_date = $this->get_tag( $post, 'wp:post_date' );
216
+ $post_date_gmt = $this->get_tag( $post, 'wp:post_date_gmt' );
217
+ $comment_status = $this->get_tag( $post, 'wp:comment_status' );
218
+ $ping_status = $this->get_tag( $post, 'wp:ping_status' );
219
+ $status = $this->get_tag( $post, 'wp:status' );
220
+ $post_name = $this->get_tag( $post, 'wp:post_name' );
221
+ $post_parent = $this->get_tag( $post, 'wp:post_parent' );
222
+ $menu_order = $this->get_tag( $post, 'wp:menu_order' );
223
+ $post_type = $this->get_tag( $post, 'wp:post_type' );
224
+ $post_password = $this->get_tag( $post, 'wp:post_password' );
225
+ $is_sticky = $this->get_tag( $post, 'wp:is_sticky' );
226
+ $guid = $this->get_tag( $post, 'guid' );
227
+ $post_author = $this->get_tag( $post, 'dc:creator' );
228
+
229
+ $post_excerpt = $this->get_tag( $post, 'excerpt:encoded' );
230
+ $post_excerpt = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_excerpt );
231
+ $post_excerpt = str_replace( '<br>', '<br />', $post_excerpt );
232
+ $post_excerpt = str_replace( '<hr>', '<hr />', $post_excerpt );
233
+
234
+ $post_content = $this->get_tag( $post, 'content:encoded' );
235
+ $post_content = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_content );
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
+ }
279
+ if ( ! empty( $post_comments ) ) {
280
+ $postdata['comments'] = $post_comments;
281
+ }
282
+
283
+ $post_meta = $this->process_meta( $post, 'wp:postmeta' );
284
+ if ( ! empty( $post_meta ) ) {
285
+ $postdata['postmeta'] = $post_meta;
286
+ }
287
+
288
+ return $postdata;
289
+ }
290
+
291
+ function _normalize_tag( $matches ) {
292
+ return '<' . strtolower( $matches[1] );
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
+ }
includes/importers/wordpress-importer/class-wxr-parser-simplexml.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress eXtended RSS file parser implementations
4
+ *
5
+ * @package WordPress
6
+ * @subpackage Importer
7
+ */
8
+
9
+ /**
10
+ * WXR Parser that makes use of the SimpleXML PHP extension.
11
+ */
12
+ class TG_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 ) );
24
+ if ( ! is_null( $old_value ) ) {
25
+ libxml_disable_entity_loader( $old_value );
26
+ }
27
+
28
+ if ( ! $success || isset( $dom->doctype ) ) {
29
+ return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'themegrill-demo-importer' ), libxml_get_errors() );
30
+ }
31
+
32
+ $xml = simplexml_import_dom( $dom );
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', 'themegrill-demo-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', 'themegrill-demo-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', 'themegrill-demo-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 {
56
+ $base_blog_url = $base_url;
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
+
137
+ $terms[] = $term;
138
+ }
139
+
140
+ // grab posts
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
+
189
+ foreach ( $wp->comment as $comment ) {
190
+ $meta = array();
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
+
217
+ $posts[] = $post;
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
+ }
includes/importers/wordpress-importer/class-wxr-parser-xml.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress eXtended RSS file parser implementations
4
+ *
5
+ * @package WordPress
6
+ * @subpackage Importer
7
+ */
8
+
9
+ /**
10
+ * WXR Parser that makes use of the XML Parser PHP extension.
11
+ */
12
+ class TG_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 );
33
+ xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
34
+ xml_set_object( $xml, $this );
35
+ xml_set_character_data_handler( $xml, 'cdata' );
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', 'themegrill-demo-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;
99
+ } else {
100
+ $this->cdata .= trim( $cdata );
101
+ }
102
+ }
103
+
104
+ function tag_close( $parser, $tag ) {
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':
136
+ case 'wp:term':
137
+ $n = substr( $tag, 3 );
138
+ array_push( $this->$n, $this->data );
139
+ $this->data = false;
140
+ break;
141
+ case 'wp:termmeta':
142
+ if ( ! empty( $this->sub_data ) ) {
143
+ $this->data['termmeta'][] = $this->sub_data;
144
+ }
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':
153
+ $this->base_url = $this->cdata;
154
+ if ( ! isset( $this->base_blog_url ) ) {
155
+ $this->base_blog_url = $this->cdata;
156
+ }
157
+ break;
158
+ case 'wp:base_blog_url':
159
+ $this->base_blog_url = $this->cdata;
160
+ break;
161
+ case 'wp:wxr_version':
162
+ $this->wxr_version = $this->cdata;
163
+ break;
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
+
175
+ $this->cdata = false;
176
+ }
177
+ }
includes/importers/wordpress-importer/class-wxr-parser.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress eXtended RSS file parser implementations
4
+ *
5
+ * @package WordPress
6
+ * @subpackage Importer
7
+ */
8
+
9
+ /**
10
+ * WordPress Importer class for managing parsing of WXR files.
11
+ */
12
+ class TG_WXR_Parser {
13
+ function parse( $file ) {
14
+ // Attempt to use proper XML parsers first
15
+ if ( extension_loaded( 'simplexml' ) ) {
16
+ $parser = new TG_WXR_Parser_SimpleXML;
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 TG_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
+ }
41
+ echo '</pre>';
42
+ echo '<p><strong>' . __( 'There was an error when reading this WXR file', 'themegrill-demo-importer' ) . '</strong><br />';
43
+ echo __( 'Details are shown above. The importer will now try again with a different parser...', 'themegrill-demo-importer' ) . '</p>';
44
+ }
45
+
46
+ // use regular expressions if nothing else available or this is bad XML
47
+ $parser = new TG_WXR_Parser_Regex;
48
+ return $parser->parse( $file );
49
+ }
50
+ }
includes/importers/wordpress-importer/class-wxr-parsers.php DELETED
@@ -1,700 +0,0 @@
1
- <?php
2
- /**
3
- * WordPress eXtended RSS file parser implementations
4
- *
5
- * Code adapted from the "WordPress Importer" plugin.
6
- *
7
- * @package WordPress
8
- * @subpackage Importer
9
- */
10
-
11
- /**
12
- * WordPress Importer class for managing parsing of WXR files.
13
- */
14
- class TG_WXR_Parser {
15
- function parse( $file ) {
16
- // Attempt to use proper XML parsers first
17
- if ( extension_loaded( 'simplexml' ) ) {
18
- $parser = new TG_WXR_Parser_SimpleXML;
19
- $result = $parser->parse( $file );
20
-
21
- // If SimpleXML succeeds or this is an invalid WXR file then return the results
22
- if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' != $result->get_error_code() )
23
- return $result;
24
- } else if ( extension_loaded( 'xml' ) ) {
25
- $parser = new TG_WXR_Parser_XML;
26
- $result = $parser->parse( $file );
27
-
28
- // If XMLParser succeeds or this is an invalid WXR file then return the results
29
- if ( ! is_wp_error( $result ) || 'XML_parse_error' != $result->get_error_code() )
30
- return $result;
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
- } else if ( 'XML_parse_error' == $result->get_error_code() ) {
40
- $error = $result->get_error_data();
41
- echo $error[0] . ':' . $error[1] . ' ' . esc_html( $error[2] );
42
- }
43
- echo '</pre>';
44
- echo '<p><strong>' . __( 'There was an error when reading this WXR file', 'themegrill-demo-importer' ) . '</strong><br />';
45
- echo __( 'Details are shown above. The importer will now try again with a different parser...', 'themegrill-demo-importer' ) . '</p>';
46
- }
47
-
48
- // use regular expressions if nothing else available or this is bad XML
49
- $parser = new TG_WXR_Parser_Regex;
50
- return $parser->parse( $file );
51
- }
52
- }
53
-
54
- /**
55
- * WXR Parser that makes use of the SimpleXML PHP extension.
56
- */
57
- class TG_WXR_Parser_SimpleXML {
58
- function parse( $file ) {
59
- $authors = $posts = $categories = $tags = $terms = array();
60
-
61
- $internal_errors = libxml_use_internal_errors(true);
62
-
63
- $dom = new DOMDocument;
64
- $old_value = null;
65
- if ( function_exists( 'libxml_disable_entity_loader' ) ) {
66
- $old_value = libxml_disable_entity_loader( true );
67
- }
68
- $success = $dom->loadXML( file_get_contents( $file ) );
69
- if ( ! is_null( $old_value ) ) {
70
- libxml_disable_entity_loader( $old_value );
71
- }
72
-
73
- if ( ! $success || isset( $dom->doctype ) ) {
74
- return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'themegrill-demo-importer' ), libxml_get_errors() );
75
- }
76
-
77
- $xml = simplexml_import_dom( $dom );
78
- unset( $dom );
79
-
80
- // halt if loading produces an error
81
- if ( ! $xml )
82
- return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this WXR file', 'themegrill-demo-importer' ), libxml_get_errors() );
83
-
84
- $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
85
- if ( ! $wxr_version )
86
- return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'themegrill-demo-importer' ) );
87
-
88
- $wxr_version = (string) trim( $wxr_version[0] );
89
- // confirm that we are dealing with the correct file format
90
- if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) )
91
- return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'themegrill-demo-importer' ) );
92
-
93
- $base_url = $xml->xpath('/rss/channel/wp:base_site_url');
94
- $base_url = (string) trim( $base_url[0] );
95
-
96
- $namespaces = $xml->getDocNamespaces();
97
- if ( ! isset( $namespaces['wp'] ) )
98
- $namespaces['wp'] = 'https://wordpress.org/export/1.1/';
99
- if ( ! isset( $namespaces['excerpt'] ) )
100
- $namespaces['excerpt'] = 'https://wordpress.org/export/1.1/excerpt/';
101
-
102
- // grab authors
103
- foreach ( $xml->xpath('/rss/channel/wp:author') as $author_arr ) {
104
- $a = $author_arr->children( $namespaces['wp'] );
105
- $login = (string) $a->author_login;
106
- $authors[$login] = array(
107
- 'author_id' => (int) $a->author_id,
108
- 'author_login' => $login,
109
- 'author_email' => (string) $a->author_email,
110
- 'author_display_name' => (string) $a->author_display_name,
111
- 'author_first_name' => (string) $a->author_first_name,
112
- 'author_last_name' => (string) $a->author_last_name
113
- );
114
- }
115
-
116
- // grab cats, tags and terms
117
- foreach ( $xml->xpath('/rss/channel/wp:category') as $term_arr ) {
118
- $t = $term_arr->children( $namespaces['wp'] );
119
- $category = array(
120
- 'term_id' => (int) $t->term_id,
121
- 'category_nicename' => (string) $t->category_nicename,
122
- 'category_parent' => (string) $t->category_parent,
123
- 'cat_name' => (string) $t->cat_name,
124
- 'category_description' => (string) $t->category_description
125
- );
126
-
127
- foreach ( $t->termmeta as $meta ) {
128
- $category['termmeta'][] = array(
129
- 'key' => (string) $meta->meta_key,
130
- 'value' => (string) $meta->meta_value
131
- );
132
- }
133
-
134
- $categories[] = $category;
135
- }
136
-
137
- foreach ( $xml->xpath('/rss/channel/wp:tag') as $term_arr ) {
138
- $t = $term_arr->children( $namespaces['wp'] );
139
- $tag = array(
140
- 'term_id' => (int) $t->term_id,
141
- 'tag_slug' => (string) $t->tag_slug,
142
- 'tag_name' => (string) $t->tag_name,
143
- 'tag_description' => (string) $t->tag_description
144
- );
145
-
146
- foreach ( $t->termmeta as $meta ) {
147
- $tag['termmeta'][] = array(
148
- 'key' => (string) $meta->meta_key,
149
- 'value' => (string) $meta->meta_value
150
- );
151
- }
152
-
153
- $tags[] = $tag;
154
- }
155
-
156
- foreach ( $xml->xpath('/rss/channel/wp:term') as $term_arr ) {
157
- $t = $term_arr->children( $namespaces['wp'] );
158
- $term = array(
159
- 'term_id' => (int) $t->term_id,
160
- 'term_taxonomy' => (string) $t->term_taxonomy,
161
- 'slug' => (string) $t->term_slug,
162
- 'term_parent' => (string) $t->term_parent,
163
- 'term_name' => (string) $t->term_name,
164
- 'term_description' => (string) $t->term_description
165
- );
166
-
167
- foreach ( $t->termmeta as $meta ) {
168
- $term['termmeta'][] = array(
169
- 'key' => (string) $meta->meta_key,
170
- 'value' => (string) $meta->meta_value
171
- );
172
- }
173
-
174
- $terms[] = $term;
175
- }
176
-
177
- // grab posts
178
- foreach ( $xml->channel->item as $item ) {
179
- $post = array(
180
- 'post_title' => (string) $item->title,
181
- 'guid' => (string) $item->guid,
182
- );
183
-
184
- $dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
185
- $post['post_author'] = (string) $dc->creator;
186
-
187
- $content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
188
- $excerpt = $item->children( $namespaces['excerpt'] );
189
- $post['post_content'] = (string) $content->encoded;
190
- $post['post_excerpt'] = (string) $excerpt->encoded;
191
-
192
- $wp = $item->children( $namespaces['wp'] );
193
- $post['post_id'] = (int) $wp->post_id;
194
- $post['post_date'] = (string) $wp->post_date;
195
- $post['post_date_gmt'] = (string) $wp->post_date_gmt;
196
- $post['comment_status'] = (string) $wp->comment_status;
197
- $post['ping_status'] = (string) $wp->ping_status;
198
- $post['post_name'] = (string) $wp->post_name;
199
- $post['status'] = (string) $wp->status;
200
- $post['post_parent'] = (int) $wp->post_parent;
201
- $post['menu_order'] = (int) $wp->menu_order;
202
- $post['post_type'] = (string) $wp->post_type;
203
- $post['post_password'] = (string) $wp->post_password;
204
- $post['is_sticky'] = (int) $wp->is_sticky;
205
-
206
- if ( isset($wp->attachment_url) )
207
- $post['attachment_url'] = (string) $wp->attachment_url;
208
-
209
- foreach ( $item->category as $c ) {
210
- $att = $c->attributes();
211
- if ( isset( $att['nicename'] ) )
212
- $post['terms'][] = array(
213
- 'name' => (string) $c,
214
- 'slug' => (string) $att['nicename'],
215
- 'domain' => (string) $att['domain']
216
- );
217
- }
218
-
219
- foreach ( $wp->postmeta as $meta ) {
220
- $post['postmeta'][] = array(
221
- 'key' => (string) $meta->meta_key,
222
- 'value' => (string) $meta->meta_value
223
- );
224
- }
225
-
226
- foreach ( $wp->comment as $comment ) {
227
- $meta = array();
228
- if ( isset( $comment->commentmeta ) ) {
229
- foreach ( $comment->commentmeta as $m ) {
230
- $meta[] = array(
231
- 'key' => (string) $m->meta_key,
232
- 'value' => (string) $m->meta_value
233
- );
234
- }
235
- }
236
-
237
- $post['comments'][] = array(
238
- 'comment_id' => (int) $comment->comment_id,
239
- 'comment_author' => (string) $comment->comment_author,
240
- 'comment_author_email' => (string) $comment->comment_author_email,
241
- 'comment_author_IP' => (string) $comment->comment_author_IP,
242
- 'comment_author_url' => (string) $comment->comment_author_url,
243
- 'comment_date' => (string) $comment->comment_date,
244
- 'comment_date_gmt' => (string) $comment->comment_date_gmt,
245
- 'comment_content' => (string) $comment->comment_content,
246
- 'comment_approved' => (string) $comment->comment_approved,
247
- 'comment_type' => (string) $comment->comment_type,
248
- 'comment_parent' => (string) $comment->comment_parent,
249
- 'comment_user_id' => (int) $comment->comment_user_id,
250
- 'commentmeta' => $meta,
251
- );
252
- }
253
-
254
- $posts[] = $post;
255
- }
256
-
257
- return array(
258
- 'authors' => $authors,
259
- 'posts' => $posts,
260
- 'categories' => $categories,
261
- 'tags' => $tags,
262
- 'terms' => $terms,
263
- 'base_url' => $base_url,
264
- 'version' => $wxr_version
265
- );
266
- }
267
- }
268
-
269
- /**
270
- * WXR Parser that makes use of the XML Parser PHP extension.
271
- */
272
- class TG_WXR_Parser_XML {
273
- var $wp_tags = array(
274
- 'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url',
275
- 'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password',
276
- 'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description',
277
- 'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent',
278
- 'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name',
279
- 'wp:author_first_name', 'wp:author_last_name',
280
- );
281
- var $wp_sub_tags = array(
282
- 'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url',
283
- 'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content',
284
- 'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id',
285
- );
286
-
287
- function parse( $file ) {
288
- $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false;
289
- $this->authors = $this->posts = $this->term = $this->category = $this->tag = array();
290
-
291
- $xml = xml_parser_create( 'UTF-8' );
292
- xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
293
- xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
294
- xml_set_object( $xml, $this );
295
- xml_set_character_data_handler( $xml, 'cdata' );
296
- xml_set_element_handler( $xml, 'tag_open', 'tag_close' );
297
-
298
- if ( ! xml_parse( $xml, file_get_contents( $file ), true ) ) {
299
- $current_line = xml_get_current_line_number( $xml );
300
- $current_column = xml_get_current_column_number( $xml );
301
- $error_code = xml_get_error_code( $xml );
302
- $error_string = xml_error_string( $error_code );
303
- return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array( $current_line, $current_column, $error_string ) );
304
- }
305
- xml_parser_free( $xml );
306
-
307
- if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) )
308
- return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'themegrill-demo-importer' ) );
309
-
310
- return array(
311
- 'authors' => $this->authors,
312
- 'posts' => $this->posts,
313
- 'categories' => $this->category,
314
- 'tags' => $this->tag,
315
- 'terms' => $this->term,
316
- 'base_url' => $this->base_url,
317
- 'version' => $this->wxr_version
318
- );
319
- }
320
-
321
- function tag_open( $parse, $tag, $attr ) {
322
- if ( in_array( $tag, $this->wp_tags ) ) {
323
- $this->in_tag = substr( $tag, 3 );
324
- return;
325
- }
326
-
327
- if ( in_array( $tag, $this->wp_sub_tags ) ) {
328
- $this->in_sub_tag = substr( $tag, 3 );
329
- return;
330
- }
331
-
332
- switch ( $tag ) {
333
- case 'category':
334
- if ( isset($attr['domain'], $attr['nicename']) ) {
335
- $this->sub_data['domain'] = $attr['domain'];
336
- $this->sub_data['slug'] = $attr['nicename'];
337
- }
338
- break;
339
- case 'item': $this->in_post = true;
340
- case 'title': if ( $this->in_post ) $this->in_tag = 'post_title'; break;
341
- case 'guid': $this->in_tag = 'guid'; break;
342
- case 'dc:creator': $this->in_tag = 'post_author'; break;
343
- case 'content:encoded': $this->in_tag = 'post_content'; break;
344
- case 'excerpt:encoded': $this->in_tag = 'post_excerpt'; break;
345
-
346
- case 'wp:term_slug': $this->in_tag = 'slug'; break;
347
- case 'wp:meta_key': $this->in_sub_tag = 'key'; break;
348
- case 'wp:meta_value': $this->in_sub_tag = 'value'; break;
349
- }
350
- }
351
-
352
- function cdata( $parser, $cdata ) {
353
- if ( ! trim( $cdata ) )
354
- return;
355
-
356
- if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
357
- $this->cdata .= $cdata;
358
- } else {
359
- $this->cdata .= trim( $cdata );
360
- }
361
- }
362
-
363
- function tag_close( $parser, $tag ) {
364
- switch ( $tag ) {
365
- case 'wp:comment':
366
- unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data
367
- if ( ! empty( $this->sub_data ) )
368
- $this->data['comments'][] = $this->sub_data;
369
- $this->sub_data = false;
370
- break;
371
- case 'wp:commentmeta':
372
- $this->sub_data['commentmeta'][] = array(
373
- 'key' => $this->sub_data['key'],
374
- 'value' => $this->sub_data['value']
375
- );
376
- break;
377
- case 'category':
378
- if ( ! empty( $this->sub_data ) ) {
379
- $this->sub_data['name'] = $this->cdata;
380
- $this->data['terms'][] = $this->sub_data;
381
- }
382
- $this->sub_data = false;
383
- break;
384
- case 'wp:postmeta':
385
- if ( ! empty( $this->sub_data ) )
386
- $this->data['postmeta'][] = $this->sub_data;
387
- $this->sub_data = false;
388
- break;
389
- case 'item':
390
- $this->posts[] = $this->data;
391
- $this->data = false;
392
- break;
393
- case 'wp:category':
394
- case 'wp:tag':
395
- case 'wp:term':
396
- $n = substr( $tag, 3 );
397
- array_push( $this->$n, $this->data );
398
- $this->data = false;
399
- break;
400
- case 'wp:author':
401
- if ( ! empty($this->data['author_login']) )
402
- $this->authors[$this->data['author_login']] = $this->data;
403
- $this->data = false;
404
- break;
405
- case 'wp:base_site_url':
406
- $this->base_url = $this->cdata;
407
- break;
408
- case 'wp:wxr_version':
409
- $this->wxr_version = $this->cdata;
410
- break;
411
-
412
- default:
413
- if ( $this->in_sub_tag ) {
414
- $this->sub_data[$this->in_sub_tag] = ! empty( $this->cdata ) ? $this->cdata : '';
415
- $this->in_sub_tag = false;
416
- } else if ( $this->in_tag ) {
417
- $this->data[$this->in_tag] = ! empty( $this->cdata ) ? $this->cdata : '';
418
- $this->in_tag = false;
419
- }
420
- }
421
-
422
- $this->cdata = false;
423
- }
424
- }
425
-
426
- /**
427
- * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
428
- */
429
- class TG_WXR_Parser_Regex {
430
- var $authors = array();
431
- var $posts = array();
432
- var $categories = array();
433
- var $tags = array();
434
- var $terms = array();
435
- var $base_url = '';
436
-
437
- function __construct() {
438
- $this->has_gzip = is_callable( 'gzopen' );
439
- }
440
-
441
- function parse( $file ) {
442
- $wxr_version = $in_multiline = false;
443
-
444
- $multiline_content = '';
445
-
446
- $multiline_tags = array(
447
- 'item' => array( 'posts', array( $this, 'process_post' ) ),
448
- 'wp:category' => array( 'categories', array( $this, 'process_category' ) ),
449
- 'wp:tag' => array( 'tags', array( $this, 'process_tag' ) ),
450
- 'wp:term' => array( 'terms', array( $this, 'process_term' ) ),
451
- );
452
-
453
- $fp = $this->fopen( $file, 'r' );
454
- if ( $fp ) {
455
- while ( ! $this->feof( $fp ) ) {
456
- $importline = rtrim( $this->fgets( $fp ) );
457
-
458
- if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) )
459
- $wxr_version = $version[1];
460
-
461
- if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
462
- preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
463
- $this->base_url = $url[1];
464
- continue;
465
- }
466
-
467
- if ( false !== strpos( $importline, '<wp:author>' ) ) {
468
- preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
469
- $a = $this->process_author( $author[1] );
470
- $this->authors[$a['author_login']] = $a;
471
- continue;
472
- }
473
-
474
- foreach ( $multiline_tags as $tag => $handler ) {
475
- // Handle multi-line tags on a singular line
476
- if ( preg_match( '|<' . $tag . '>(.*?)</' . $tag . '>|is', $importline, $matches ) ) {
477
- $this->{$handler[0]}[] = call_user_func( $handler[1], $matches[1] );
478
-
479
- } elseif ( false !== ( $pos = strpos( $importline, "<$tag>" ) ) ) {
480
- // Take note of any content after the opening tag
481
- $multiline_content = trim( substr( $importline, $pos + strlen( $tag ) + 2 ) );
482
-
483
- // We don't want to have this line added to `$is_multiline` below.
484
- $importline = '';
485
- $in_multiline = $tag;
486
-
487
- } elseif ( false !== ( $pos = strpos( $importline, "</$tag>" ) ) ) {
488
- $in_multiline = false;
489
- $multiline_content .= trim( substr( $importline, 0, $pos ) );
490
-
491
- $this->{$handler[0]}[] = call_user_func( $handler[1], $multiline_content );
492
- }
493
- }
494
-
495
- if ( $in_multiline && $importline ) {
496
- $multiline_content .= $importline . "\n";
497
- }
498
- }
499
-
500
- $this->fclose($fp);
501
- }
502
-
503
- if ( ! $wxr_version )
504
- return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'themegrill-demo-importer' ) );
505
-
506
- return array(
507
- 'authors' => $this->authors,
508
- 'posts' => $this->posts,
509
- 'categories' => $this->categories,
510
- 'tags' => $this->tags,
511
- 'terms' => $this->terms,
512
- 'base_url' => $this->base_url,
513
- 'version' => $wxr_version
514
- );
515
- }
516
-
517
- function get_tag( $string, $tag ) {
518
- preg_match( "|<$tag.*?>(.*?)</$tag>|is", $string, $return );
519
- if ( isset( $return[1] ) ) {
520
- if ( substr( $return[1], 0, 9 ) == '<![CDATA[' ) {
521
- if ( strpos( $return[1], ']]]]><![CDATA[>' ) !== false ) {
522
- preg_match_all( '|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches );
523
- $return = '';
524
- foreach( $matches[1] as $match )
525
- $return .= $match;
526
- } else {
527
- $return = preg_replace( '|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1] );
528
- }
529
- } else {
530
- $return = $return[1];
531
- }
532
- } else {
533
- $return = '';
534
- }
535
- return $return;
536
- }
537
-
538
- function process_category( $c ) {
539
- return array(
540
- 'term_id' => $this->get_tag( $c, 'wp:term_id' ),
541
- 'cat_name' => $this->get_tag( $c, 'wp:cat_name' ),
542
- 'category_nicename' => $this->get_tag( $c, 'wp:category_nicename' ),
543
- 'category_parent' => $this->get_tag( $c, 'wp:category_parent' ),
544
- 'category_description' => $this->get_tag( $c, 'wp:category_description' ),
545
- );
546
- }
547
-
548
- function process_tag( $t ) {
549
- return array(
550
- 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
551
- 'tag_name' => $this->get_tag( $t, 'wp:tag_name' ),
552
- 'tag_slug' => $this->get_tag( $t, 'wp:tag_slug' ),
553
- 'tag_description' => $this->get_tag( $t, 'wp:tag_description' ),
554
- );
555
- }
556
-
557
- function process_term( $t ) {
558
- return array(
559
- 'term_id' => $this->get_tag( $t, 'wp:term_id' ),
560
- 'term_taxonomy' => $this->get_tag( $t, 'wp:term_taxonomy' ),
561
- 'slug' => $this->get_tag( $t, 'wp:term_slug' ),
562
- 'term_parent' => $this->get_tag( $t, 'wp:term_parent' ),
563
- 'term_name' => $this->get_tag( $t, 'wp:term_name' ),
564
- 'term_description' => $this->get_tag( $t, 'wp:term_description' ),
565
- );
566
- }
567
-
568
- function process_author( $a ) {
569
- return array(
570
- 'author_id' => $this->get_tag( $a, 'wp:author_id' ),
571
- 'author_login' => $this->get_tag( $a, 'wp:author_login' ),
572
- 'author_email' => $this->get_tag( $a, 'wp:author_email' ),
573
- 'author_display_name' => $this->get_tag( $a, 'wp:author_display_name' ),
574
- 'author_first_name' => $this->get_tag( $a, 'wp:author_first_name' ),
575
- 'author_last_name' => $this->get_tag( $a, 'wp:author_last_name' ),
576
- );
577
- }
578
-
579
- function process_post( $post ) {
580
- $post_id = $this->get_tag( $post, 'wp:post_id' );
581
- $post_title = $this->get_tag( $post, 'title' );
582
- $post_date = $this->get_tag( $post, 'wp:post_date' );
583
- $post_date_gmt = $this->get_tag( $post, 'wp:post_date_gmt' );
584
- $comment_status = $this->get_tag( $post, 'wp:comment_status' );
585
- $ping_status = $this->get_tag( $post, 'wp:ping_status' );
586
- $status = $this->get_tag( $post, 'wp:status' );
587
- $post_name = $this->get_tag( $post, 'wp:post_name' );
588
- $post_parent = $this->get_tag( $post, 'wp:post_parent' );
589
- $menu_order = $this->get_tag( $post, 'wp:menu_order' );
590
- $post_type = $this->get_tag( $post, 'wp:post_type' );
591
- $post_password = $this->get_tag( $post, 'wp:post_password' );
592
- $is_sticky = $this->get_tag( $post, 'wp:is_sticky' );
593
- $guid = $this->get_tag( $post, 'guid' );
594
- $post_author = $this->get_tag( $post, 'dc:creator' );
595
-
596
- $post_excerpt = $this->get_tag( $post, 'excerpt:encoded' );
597
- $post_excerpt = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_excerpt );
598
- $post_excerpt = str_replace( '<br>', '<br />', $post_excerpt );
599
- $post_excerpt = str_replace( '<hr>', '<hr />', $post_excerpt );
600
-
601
- $post_content = $this->get_tag( $post, 'content:encoded' );
602
- $post_content = preg_replace_callback( '|<(/?[A-Z]+)|', array( &$this, '_normalize_tag' ), $post_content );
603
- $post_content = str_replace( '<br>', '<br />', $post_content );
604
- $post_content = str_replace( '<hr>', '<hr />', $post_content );
605
-
606
- $postdata = compact( 'post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt',
607
- 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent',
608
- 'menu_order', 'post_type', 'post_password', 'is_sticky'
609
- );
610
-
611
- $attachment_url = $this->get_tag( $post, 'wp:attachment_url' );
612
- if ( $attachment_url )
613
- $postdata['attachment_url'] = $attachment_url;
614
-
615
- preg_match_all( '|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER );
616
- foreach ( $terms as $t ) {
617
- $post_terms[] = array(
618
- 'slug' => $t[2],
619
- 'domain' => $t[1],
620
- 'name' => str_replace( array( '<![CDATA[', ']]>' ), '', $t[3] ),
621
- );
622
- }
623
- if ( ! empty( $post_terms ) ) $postdata['terms'] = $post_terms;
624
-
625
- preg_match_all( '|<wp:comment>(.+?)</wp:comment>|is', $post, $comments );
626
- $comments = $comments[1];
627
- if ( $comments ) {
628
- foreach ( $comments as $comment ) {
629
- preg_match_all( '|<wp:commentmeta>(.+?)</wp:commentmeta>|is', $comment, $commentmeta );
630
- $commentmeta = $commentmeta[1];
631
- $c_meta = array();
632
- foreach ( $commentmeta as $m ) {
633
- $c_meta[] = array(
634
- 'key' => $this->get_tag( $m, 'wp:meta_key' ),
635
- 'value' => $this->get_tag( $m, 'wp:meta_value' ),
636
- );
637
- }
638
-
639
- $post_comments[] = array(
640
- 'comment_id' => $this->get_tag( $comment, 'wp:comment_id' ),
641
- 'comment_author' => $this->get_tag( $comment, 'wp:comment_author' ),
642
- 'comment_author_email' => $this->get_tag( $comment, 'wp:comment_author_email' ),
643
- 'comment_author_IP' => $this->get_tag( $comment, 'wp:comment_author_IP' ),
644
- 'comment_author_url' => $this->get_tag( $comment, 'wp:comment_author_url' ),
645
- 'comment_date' => $this->get_tag( $comment, 'wp:comment_date' ),
646
- 'comment_date_gmt' => $this->get_tag( $comment, 'wp:comment_date_gmt' ),
647
- 'comment_content' => $this->get_tag( $comment, 'wp:comment_content' ),
648
- 'comment_approved' => $this->get_tag( $comment, 'wp:comment_approved' ),
649
- 'comment_type' => $this->get_tag( $comment, 'wp:comment_type' ),
650
- 'comment_parent' => $this->get_tag( $comment, 'wp:comment_parent' ),
651
- 'comment_user_id' => $this->get_tag( $comment, 'wp:comment_user_id' ),
652
- 'commentmeta' => $c_meta,
653
- );
654
- }
655
- }
656
- if ( ! empty( $post_comments ) ) $postdata['comments'] = $post_comments;
657
-
658
- preg_match_all( '|<wp:postmeta>(.+?)</wp:postmeta>|is', $post, $postmeta );
659
- $postmeta = $postmeta[1];
660
- if ( $postmeta ) {
661
- foreach ( $postmeta as $p ) {
662
- $post_postmeta[] = array(
663
- 'key' => $this->get_tag( $p, 'wp:meta_key' ),
664
- 'value' => $this->get_tag( $p, 'wp:meta_value' ),
665
- );
666
- }
667
- }
668
- if ( ! empty( $post_postmeta ) ) $postdata['postmeta'] = $post_postmeta;
669
-
670
- return $postdata;
671
- }
672
-
673
- function _normalize_tag( $matches ) {
674
- return '<' . strtolower( $matches[1] );
675
- }
676
-
677
- function fopen( $filename, $mode = 'r' ) {
678
- if ( $this->has_gzip )
679
- return gzopen( $filename, $mode );
680
- return fopen( $filename, $mode );
681
- }
682
-
683
- function feof( $fp ) {
684
- if ( $this->has_gzip )
685
- return gzeof( $fp );
686
- return feof( $fp );
687
- }
688
-
689
- function fgets( $fp, $len = 8192 ) {
690
- if ( $this->has_gzip )
691
- return gzgets( $fp, $len );
692
- return fgets( $fp, $len );
693
- }
694
-
695
- function fclose( $fp ) {
696
- if ( $this->has_gzip )
697
- return gzclose( $fp );
698
- return fclose( $fp );
699
- }
700
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/themegrill-demo-importer.pot CHANGED
@@ -2,10 +2,10 @@
2
  # This file is distributed under the GPLv3 or later.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: ThemeGrill Demo Importer 1.6.4\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://github.com/themegrill/themegrill-demo-importer/issues\n"
8
- "POT-Creation-Date: 2020-06-04 06:28:04+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -646,210 +646,227 @@ msgstr ""
646
  msgid "No Title"
647
  msgstr ""
648
 
649
- #: includes/importers/wordpress-importer/class-wxr-importer.php:124
650
- #: includes/importers/wordpress-importer/class-wxr-importer.php:133
651
- #: includes/importers/wordpress-importer/class-wxr-importer.php:184
652
- #: includes/importers/wordpress-importer/class-wxr-importer.php:188
653
- #: includes/importers/wordpress-importer/class-wxr-importer.php:197
654
  msgid "Sorry, there has been an error."
655
  msgstr ""
656
 
657
- #: includes/importers/wordpress-importer/class-wxr-importer.php:125
658
  msgid "The file does not exist, please try again."
659
  msgstr ""
660
 
661
- #: includes/importers/wordpress-importer/class-wxr-importer.php:168
662
  msgid "All done."
663
  msgstr ""
664
 
665
- #: includes/importers/wordpress-importer/class-wxr-importer.php:168
666
  msgid "Have fun!"
667
  msgstr ""
668
 
669
- #: includes/importers/wordpress-importer/class-wxr-importer.php:169
670
  msgid "Remember to update the passwords and roles of imported users."
671
  msgstr ""
672
 
673
- #: includes/importers/wordpress-importer/class-wxr-importer.php:189
674
  msgid ""
675
  "The export file could not be found at <code>%s</code>. It is likely that "
676
  "this was caused by a permissions problem."
677
  msgstr ""
678
 
679
- #: includes/importers/wordpress-importer/class-wxr-importer.php:205
680
  msgid ""
681
  "This WXR file (version %s) may not be supported by this version of the "
682
  "importer. Please consider updating."
683
  msgstr ""
684
 
685
- #: includes/importers/wordpress-importer/class-wxr-importer.php:230
686
  msgid ""
687
  "Failed to import author %s. Their posts will be attributed to the current "
688
  "user."
689
  msgstr ""
690
 
691
- #: includes/importers/wordpress-importer/class-wxr-importer.php:257
692
  msgid "Assign Authors"
693
  msgstr ""
694
 
695
- #: includes/importers/wordpress-importer/class-wxr-importer.php:258
696
  msgid ""
697
- "To make it easier for you to edit and save the imported content, you may "
698
  "want to reassign the author of the imported item to an existing user of "
699
- "this site. For example, you may want to import all the entries as "
700
- "<code>admin</code>s entries."
701
  msgstr ""
702
 
703
- #: includes/importers/wordpress-importer/class-wxr-importer.php:260
704
  msgid ""
705
  "If a new user is created by WordPress, a new password will be randomly "
706
  "generated and the new user&#8217;s role will be set as %s. Manually "
707
  "changing the new user&#8217;s details will be necessary."
708
  msgstr ""
709
 
710
- #: includes/importers/wordpress-importer/class-wxr-importer.php:270
711
  msgid "Import Attachments"
712
  msgstr ""
713
 
714
- #: includes/importers/wordpress-importer/class-wxr-importer.php:273
715
  msgid "Download and import file attachments"
716
  msgstr ""
717
 
718
- #: includes/importers/wordpress-importer/class-wxr-importer.php:277
719
  msgid "Submit"
720
  msgstr ""
721
 
722
- #: includes/importers/wordpress-importer/class-wxr-importer.php:290
723
  msgid "Import author:"
724
  msgstr ""
725
 
726
- #: includes/importers/wordpress-importer/class-wxr-importer.php:304
727
  msgid "or create new user with login name:"
728
  msgstr ""
729
 
730
- #: includes/importers/wordpress-importer/class-wxr-importer.php:307
731
  msgid "as a new user:"
732
  msgstr ""
733
 
734
- #: includes/importers/wordpress-importer/class-wxr-importer.php:315
735
  msgid "assign posts to an existing user:"
736
  msgstr ""
737
 
738
- #: includes/importers/wordpress-importer/class-wxr-importer.php:317
739
  msgid "or assign posts to an existing user:"
740
  msgstr ""
741
 
742
- #: includes/importers/wordpress-importer/class-wxr-importer.php:323
743
  msgid "- Select -"
744
  msgstr ""
745
 
746
- #: includes/importers/wordpress-importer/class-wxr-importer.php:382
747
  msgid ""
748
  "Failed to create new user for %s. Their posts will be attributed to the "
749
  "current user."
750
  msgstr ""
751
 
752
- #: includes/importers/wordpress-importer/class-wxr-importer.php:441
753
  msgid "Failed to import category %s"
754
  msgstr ""
755
 
756
- #: includes/importers/wordpress-importer/class-wxr-importer.php:493
757
  msgid "Failed to import post tag %s"
758
  msgstr ""
759
 
760
- #: includes/importers/wordpress-importer/class-wxr-importer.php:554
761
- #: includes/importers/wordpress-importer/class-wxr-importer.php:799
762
- msgid "Failed to import %1$s %2$s"
763
  msgstr ""
764
 
765
- #: includes/importers/wordpress-importer/class-wxr-importer.php:645
766
- msgid "Failed to import &#8220;%1$s&#8221;: Invalid post type %2$s"
767
  msgstr ""
768
 
769
- #: includes/importers/wordpress-importer/class-wxr-importer.php:686
770
- msgid "%1$s &#8220;%2$s&#8221; already exists."
771
  msgstr ""
772
 
773
- #: includes/importers/wordpress-importer/class-wxr-importer.php:760
774
- msgid "Failed to import %1$s &#8220;%2$s&#8221;"
775
  msgstr ""
776
 
777
- #: includes/importers/wordpress-importer/class-wxr-importer.php:940
778
  msgid "Menu item skipped due to missing menu slug"
779
  msgstr ""
780
 
781
- #: includes/importers/wordpress-importer/class-wxr-importer.php:947
782
  msgid "Menu item skipped due to invalid menu slug: %s"
783
  msgstr ""
784
 
785
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1018
786
  msgid "Fetching attachments is not enabled"
787
  msgstr ""
788
 
789
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1035
790
  msgid "Invalid file type"
791
  msgstr ""
792
 
793
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1090
794
- msgid "Remote server did not respond"
795
  msgstr ""
796
 
797
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1098
798
- msgid "Remote server returned error response %1$d %2$s"
 
799
  msgstr ""
800
 
801
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1105
802
- msgid "Remote file is incorrect size"
 
 
 
 
 
803
  msgstr ""
804
 
805
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1110
806
  msgid "Zero size file downloaded"
807
  msgstr ""
808
 
809
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1116
 
 
 
 
810
  msgid "Remote file is too large, limit is %s"
811
  msgstr ""
812
 
813
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1224
 
 
 
 
 
 
 
 
814
  msgid "Import WordPress"
815
  msgstr ""
816
 
817
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1231
818
  msgid ""
819
  "A new version of this importer is available. Please update to version %s to "
820
  "ensure compatibility with newer export files."
821
  msgstr ""
822
 
823
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1246
824
  msgid ""
825
  "Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import "
826
  "the posts, pages, comments, custom fields, categories, and tags into this "
827
  "site."
828
  msgstr ""
829
 
830
- #: includes/importers/wordpress-importer/class-wxr-importer.php:1247
831
  msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
832
  msgstr ""
833
 
834
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:44
835
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:74
836
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:82
 
 
 
 
 
 
 
837
  msgid "There was an error when reading this WXR file"
838
  msgstr ""
839
 
840
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:45
841
  msgid ""
842
  "Details are shown above. The importer will now try again with a different "
843
  "parser..."
844
  msgstr ""
845
 
846
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:86
847
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:91
848
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:308
849
- #: includes/importers/wordpress-importer/class-wxr-parsers.php:504
850
- msgid "This does not appear to be a WXR file, missing/invalid WXR version number"
851
- msgstr ""
852
-
853
  #. Plugin URI of the plugin/theme
854
  msgid "https://themegrill.com/demo-importer/"
855
  msgstr ""
2
  # This file is distributed under the GPLv3 or later.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: ThemeGrill Demo Importer 1.6.5\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://github.com/themegrill/themegrill-demo-importer/issues\n"
8
+ "POT-Creation-Date: 2020-07-23 09:12:51+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
646
  msgid "No Title"
647
  msgstr ""
648
 
649
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:132
650
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:141
651
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:192
652
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:196
653
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:205
654
  msgid "Sorry, there has been an error."
655
  msgstr ""
656
 
657
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:133
658
  msgid "The file does not exist, please try again."
659
  msgstr ""
660
 
661
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:176
662
  msgid "All done."
663
  msgstr ""
664
 
665
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:176
666
  msgid "Have fun!"
667
  msgstr ""
668
 
669
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:177
670
  msgid "Remember to update the passwords and roles of imported users."
671
  msgstr ""
672
 
673
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:197
674
  msgid ""
675
  "The export file could not be found at <code>%s</code>. It is likely that "
676
  "this was caused by a permissions problem."
677
  msgstr ""
678
 
679
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:213
680
  msgid ""
681
  "This WXR file (version %s) may not be supported by this version of the "
682
  "importer. Please consider updating."
683
  msgstr ""
684
 
685
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:238
686
  msgid ""
687
  "Failed to import author %s. Their posts will be attributed to the current "
688
  "user."
689
  msgstr ""
690
 
691
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:264
692
  msgid "Assign Authors"
693
  msgstr ""
694
 
695
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:265
696
  msgid ""
697
+ "To make it simpler for you to edit and save the imported content, you may "
698
  "want to reassign the author of the imported item to an existing user of "
699
+ "this site, such as your primary administrator account."
 
700
  msgstr ""
701
 
702
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:267
703
  msgid ""
704
  "If a new user is created by WordPress, a new password will be randomly "
705
  "generated and the new user&#8217;s role will be set as %s. Manually "
706
  "changing the new user&#8217;s details will be necessary."
707
  msgstr ""
708
 
709
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:277
710
  msgid "Import Attachments"
711
  msgstr ""
712
 
713
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:280
714
  msgid "Download and import file attachments"
715
  msgstr ""
716
 
717
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:284
718
  msgid "Submit"
719
  msgstr ""
720
 
721
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:297
722
  msgid "Import author:"
723
  msgstr ""
724
 
725
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:309
726
  msgid "or create new user with login name:"
727
  msgstr ""
728
 
729
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:312
730
  msgid "as a new user:"
731
  msgstr ""
732
 
733
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:322
734
  msgid "assign posts to an existing user:"
735
  msgstr ""
736
 
737
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:324
738
  msgid "or assign posts to an existing user:"
739
  msgstr ""
740
 
741
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:332
742
  msgid "- Select -"
743
  msgstr ""
744
 
745
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:386
746
  msgid ""
747
  "Failed to create new user for %s. Their posts will be attributed to the "
748
  "current user."
749
  msgstr ""
750
 
751
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:438
752
  msgid "Failed to import category %s"
753
  msgstr ""
754
 
755
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:483
756
  msgid "Failed to import post tag %s"
757
  msgstr ""
758
 
759
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:538
760
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:764
761
+ msgid "Failed to import %s %s"
762
  msgstr ""
763
 
764
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:631
765
+ msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
766
  msgstr ""
767
 
768
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:668
769
+ msgid "%s &#8220;%s&#8221; already exists."
770
  msgstr ""
771
 
772
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:730
773
+ msgid "Failed to import %s &#8220;%s&#8221;"
774
  msgstr ""
775
 
776
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:904
777
  msgid "Menu item skipped due to missing menu slug"
778
  msgstr ""
779
 
780
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:911
781
  msgid "Menu item skipped due to invalid menu slug: %s"
782
  msgstr ""
783
 
784
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:974
785
  msgid "Fetching attachments is not enabled"
786
  msgstr ""
787
 
788
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:987
789
  msgid "Invalid file type"
790
  msgstr ""
791
 
792
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1026
793
+ msgid "Could not create temporary file."
794
  msgstr ""
795
 
796
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1045
797
+ #. translators: 1: The WordPress error message. 2: The WordPress error code.
798
+ msgid "Request failed due to an error: %1$s (%2$s)"
799
  msgstr ""
800
 
801
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1061
802
+ #. translators: 1: The HTTP error message. 2: The HTTP error code.
803
+ msgid "Remote server returned the following unexpected result: %1$s (%2$s)"
804
+ msgstr ""
805
+
806
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1073
807
+ msgid "Remote server did not respond"
808
  msgstr ""
809
 
810
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1080
811
  msgid "Zero size file downloaded"
812
  msgstr ""
813
 
814
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1085
815
+ msgid "Downloaded file has incorrect size"
816
+ msgstr ""
817
+
818
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1091
819
  msgid "Remote file is too large, limit is %s"
820
  msgstr ""
821
 
822
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1123
823
+ msgid "Sorry, this file type is not permitted for security reasons."
824
+ msgstr ""
825
+
826
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1138
827
+ msgid "The uploaded file could not be moved"
828
+ msgstr ""
829
+
830
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1250
831
  msgid "Import WordPress"
832
  msgstr ""
833
 
834
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1257
835
  msgid ""
836
  "A new version of this importer is available. Please update to version %s to "
837
  "ensure compatibility with newer export files."
838
  msgstr ""
839
 
840
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1272
841
  msgid ""
842
  "Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import "
843
  "the posts, pages, comments, custom fields, categories, and tags into this "
844
  "site."
845
  msgstr ""
846
 
847
+ #: includes/importers/wordpress-importer/class-wxr-importer.php:1273
848
  msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
849
  msgstr ""
850
 
851
+ #: includes/importers/wordpress-importer/class-wxr-parser-regex.php:96
852
+ #: includes/importers/wordpress-importer/class-wxr-parser-simplexml.php:41
853
+ #: includes/importers/wordpress-importer/class-wxr-parser-simplexml.php:46
854
+ #: includes/importers/wordpress-importer/class-wxr-parser-xml.php:48
855
+ msgid "This does not appear to be a WXR file, missing/invalid WXR version number"
856
+ msgstr ""
857
+
858
+ #: includes/importers/wordpress-importer/class-wxr-parser-simplexml.php:29
859
+ #: includes/importers/wordpress-importer/class-wxr-parser-simplexml.php:37
860
+ #: includes/importers/wordpress-importer/class-wxr-parser.php:42
861
  msgid "There was an error when reading this WXR file"
862
  msgstr ""
863
 
864
+ #: includes/importers/wordpress-importer/class-wxr-parser.php:43
865
  msgid ""
866
  "Details are shown above. The importer will now try again with a different "
867
  "parser..."
868
  msgstr ""
869
 
 
 
 
 
 
 
 
870
  #. Plugin URI of the plugin/theme
871
  msgid "https://themegrill.com/demo-importer/"
872
  msgstr ""
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: ThemeGrill, shivapoudel
3
  Tags: themegrill, theme demos, demo, importer, one click import
4
  Requires at least: 4.7
5
  Tested up to: 5.4
6
- Stable tag: 1.6.4
7
  License: GPLv3 or later
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -72,6 +72,9 @@ Yes you can! Join in on our [GitHub repository](https://github.com/themegrill/th
72
  3. Finally, Import the Demo with just one click.
73
 
74
  == Changelog ==
 
 
 
75
  = 1.6.4 - 04-06-2020 =
76
  * Fix - `WooCommerce Setup Wizard` disabled when the plugin is active.
77
  * Fix - `Live Preview` button link on successful demo import message in WordPress multisite install.
3
  Tags: themegrill, theme demos, demo, importer, one click import
4
  Requires at least: 4.7
5
  Tested up to: 5.4
6
+ Stable tag: 1.6.5
7
  License: GPLv3 or later
8
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
9
 
72
  3. Finally, Import the Demo with just one click.
73
 
74
  == Changelog ==
75
+ = 1.6.5 - 23-07-2020 =
76
+ * Fix - Demo not importing completely in certain conditions.
77
+
78
  = 1.6.4 - 04-06-2020 =
79
  * Fix - `WooCommerce Setup Wizard` disabled when the plugin is active.
80
  * Fix - `Live Preview` button link on successful demo import message in WordPress multisite install.
themegrill-demo-importer.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ThemeGrill Demo Importer
4
  * Plugin URI: https://themegrill.com/demo-importer/
5
  * Description: Import ThemeGrill official themes demo content, widgets and theme settings with just one click.
6
- * Version: 1.6.4
7
  * Author: ThemeGrill
8
  * Author URI: https://themegrill.com
9
  * License: GPLv3 or later
3
  * Plugin Name: ThemeGrill Demo Importer
4
  * Plugin URI: https://themegrill.com/demo-importer/
5
  * Description: Import ThemeGrill official themes demo content, widgets and theme settings with just one click.
6
+ * Version: 1.6.5
7
  * Author: ThemeGrill
8
  * Author URI: https://themegrill.com
9
  * License: GPLv3 or later