Acme Demo Setup - Version 1.0.5

Version Description

Download this release

Release Info

Developer acmethemes
Plugin Icon 128x128 Acme Demo Setup
Version 1.0.5
Comparing to
See all releases

Code changes from version 1.0.4 to 1.0.5

acme-demo-setup.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Acme Demo Setup
4
  Plugin URI:
5
  Description: One click demo import
6
- Version: 1.0.4
7
  Author: Acme Themes
8
  Author URI: https://www.acmethemes.com/
9
  License: GPLv2 or later
3
  Plugin Name: Acme Demo Setup
4
  Plugin URI:
5
  Description: One click demo import
6
+ Version: 1.0.5
7
  Author: Acme Themes
8
  Author URI: https://www.acmethemes.com/
9
  License: GPLv2 or later
inc/admin/upload.php CHANGED
@@ -27,8 +27,8 @@ if( !class_exists( 'Acme_Demo_Setup') ):
27
  wp_enqueue_script( 'acme-demo-setup', ACME_DEMO_SETUP_URL.'inc/assets/js/acme-demo-setup.js', array( 'jquery' ) );
28
  wp_localize_script( 'acme-demo-setup', 'acme_demo_setup_object', array(
29
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
30
- 'importing' => esc_html__('Importing','education-base'),
31
- 'imported' => esc_html__('Task Completed, view the log below','education-base')
32
  ) );
33
  }
34
  }
@@ -215,10 +215,11 @@ if( !class_exists( 'Acme_Demo_Setup') ):
215
  echo '<p>'. sprintf( __( 'Maximum upload file size: %s','acme-demo-setup' ), size_format( wp_max_upload_size() ) ) .'</p>';
216
  wp_nonce_field( 'acme-demo-setup' );
217
  submit_button( __( 'Upload and Import', 'acme-demo-setup' ) );
218
- echo "<div id='at-demo-ajax-install-error' style='display: none;color: #d54e21'>".esc_html__('Select File and Try Again!','education-base')."</div>";
219
  echo '</form>';
220
- echo "<span id='at-demo-ajax-install-result-loading' class='button button-primary' style='display: none'>".esc_html__('Importing...','education-base')."</span>";
221
- echo "<h4 id='at-demo-ajax-install-result-title' style='display: none'>".esc_html__('Task Completed, view the log below','education-base')."</h4>";
 
222
  echo "<div id='at-demo-ajax-install-result'></div>";
223
  }
224
 
27
  wp_enqueue_script( 'acme-demo-setup', ACME_DEMO_SETUP_URL.'inc/assets/js/acme-demo-setup.js', array( 'jquery' ) );
28
  wp_localize_script( 'acme-demo-setup', 'acme_demo_setup_object', array(
29
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
30
+ 'importing' => esc_html__('Importing','acme-demo-setup'),
31
+ 'imported' => esc_html__('Task Completed, view the log below','acme-demo-setup')
32
  ) );
33
  }
34
  }
215
  echo '<p>'. sprintf( __( 'Maximum upload file size: %s','acme-demo-setup' ), size_format( wp_max_upload_size() ) ) .'</p>';
216
  wp_nonce_field( 'acme-demo-setup' );
217
  submit_button( __( 'Upload and Import', 'acme-demo-setup' ) );
218
+ echo "<div id='at-demo-ajax-install-error' style='display: none;color: #d54e21'>".esc_html__('Select File and Try Again!','acme-demo-setup')."</div>";
219
  echo '</form>';
220
+ echo "<span id='at-demo-ajax-install-result-loading' class='button button-primary' style='display: none'>".esc_html__('Importing...','acme-demo-setup')."<img src='".admin_url()."images/loading.gif' style='padding-left:15px'>"."</span>";
221
+ echo "<h4 id='at-demo-ajax-install-result-title' style='display: none'>".esc_html__('Task Completed, view the log below','acme-demo-setup')."</h4>";
222
+ echo "<h4 id='at-demo-ajax-install-result-error' style='display: none'>".sprintf( esc_html__('Some Error Occur While Importing Demo, Please contact %s theme support %s ','acme-demo-setup'),'<a href="https://www.acmethemes.com/supports/" target="_blank">','</a>' )."</h4>";
223
  echo "<div id='at-demo-ajax-install-result'></div>";
224
  }
225
 
inc/assets/js/acme-demo-setup.js CHANGED
@@ -40,6 +40,8 @@ jQuery(document).ready(function ($) {
40
  jQuery('#at-demo-ajax-install-result').html(data);
41
  },
42
  error : function (jqXHR, textStatus, errorThrown) {
 
 
43
  console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);
44
  }
45
  });
40
  jQuery('#at-demo-ajax-install-result').html(data);
41
  },
42
  error : function (jqXHR, textStatus, errorThrown) {
43
+ jQuery('#at-demo-ajax-install-result-loading').hide();
44
+ jQuery('#at-demo-ajax-install-result-error').show();
45
  console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);
46
  }
47
  });
inc/frameworks/wordpress-importer/wordpress-importer.php CHANGED
@@ -24,1000 +24,1000 @@ require dirname(__FILE__) . '/parsers.php';
24
  * Renaming WP_Import to Acme_Demo_Setup_Wp_Import
25
  */
26
  if ( class_exists( 'WP_Importer' ) ) {
27
- class Acme_Demo_Setup_Wp_Import extends WP_Importer {
28
- var $max_wxr_version = 1.2; // max. supported WXR version
29
-
30
- var $id; // WXR attachment ID
31
-
32
- // information to import from WXR file
33
- var $version;
34
- var $authors = array();
35
- var $posts = array();
36
- var $terms = array();
37
- var $categories = array();
38
- var $tags = array();
39
- var $base_url = '';
40
-
41
- // mappings from old information to new
42
- var $processed_authors = array();
43
- var $author_mapping = array();
44
- var $processed_terms = array();
45
- var $processed_posts = array();
46
- var $post_orphans = array();
47
- var $processed_menu_items = array();
48
- var $menu_item_orphans = array();
49
- var $missing_menu_items = array();
50
-
51
- var $fetch_attachments = false;
52
- var $url_remap = array();
53
- var $featured_images = array();
54
-
55
- /**
56
- * The main controller for the actual import stage.
57
- *
58
- * @param string $file Path to the WXR file for importing
59
- */
60
- function import( $file ) {
61
-
62
- add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) );
63
- add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
64
-
65
- $this->import_start( $file );
66
-
67
- $this->get_author_mapping();
68
-
69
- wp_suspend_cache_invalidation( true );
70
- $this->process_categories();
71
- $this->process_tags();
72
- $this->process_terms();
73
- $this->process_posts();
74
- wp_suspend_cache_invalidation( false );
75
-
76
- // update incorrect/missing information in the DB
77
- $this->backfill_parents();
78
- $this->backfill_attachment_urls();
79
- $this->remap_featured_images();
80
-
81
- $this->import_end();
82
- }
83
 
84
- /**
85
- * Parses the WXR file and prepares us for the task of processing parsed data
86
- *
87
- * @param string $file Path to the WXR file for importing
88
- */
89
- function import_start( $file ) {
90
-
91
- if ( ! is_file($file) ) {
92
- echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
93
- echo __( 'The file does not exist, please try again.', 'wordpress-importer' ) . '</p>';
94
- die();
95
- }
 
96
 
97
- $import_data = $this->parse( $file );
 
 
 
 
 
98
 
99
- if ( is_wp_error( $import_data ) ) {
100
- echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
101
- echo esc_html( $import_data->get_error_message() ) . '</p>';
102
- die();
 
 
103
  }
104
 
105
- $this->version = $import_data['version'];
106
- $this->get_authors_from_import( $import_data );
107
- $this->posts = $import_data['posts'];
108
- $this->terms = $import_data['terms'];
109
- $this->categories = $import_data['categories'];
110
- $this->tags = $import_data['tags'];
111
- $this->base_url = esc_url( $import_data['base_url'] );
 
 
 
 
 
112
 
113
- wp_defer_term_counting( true );
114
- wp_defer_comment_counting( true );
115
 
116
- do_action( 'import_start' );
117
- }
 
 
 
118
 
119
- /**
120
- * Performs post-import cleanup of files and the cache
121
- */
122
- function import_end() {
123
- wp_import_cleanup( $this->id );
 
 
124
 
125
- wp_cache_flush();
126
- foreach ( get_taxonomies() as $tax ) {
127
- delete_option( "{$tax}_children" );
128
- _get_term_hierarchy( $tax );
129
  }
130
 
131
- wp_defer_term_counting( false );
132
- wp_defer_comment_counting( false );
 
 
 
133
 
134
- echo '<p>' . __( 'Remember to update the passwords and roles of imported users.', 'wordpress-importer' ) . '</p>';
 
 
 
 
135
 
136
- do_action( 'import_end' );
137
- }
138
 
 
139
 
140
- /**
141
- * Retrieve authors from parsed WXR data
142
- *
143
- * Uses the provided author information from WXR 1.1 files
144
- * or extracts info from each post for WXR 1.0 files
145
- *
146
- * @param array $import_data Data returned by a WXR parser
147
- */
148
- function get_authors_from_import( $import_data ) {
149
- if ( ! empty( $import_data['authors'] ) ) {
150
- $this->authors = $import_data['authors'];
151
- // no author information, grab it from the posts
152
- } else {
153
- foreach ( $import_data['posts'] as $post ) {
154
- $login = sanitize_user( $post['post_author'], true );
155
- if ( empty( $login ) ) {
156
- printf( __( 'Failed to import author %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html( $post['post_author'] ) );
157
- echo '<br />';
158
- continue;
159
- }
160
 
161
- if ( ! isset($this->authors[$login]) )
162
- $this->authors[$login] = array(
163
- 'author_login' => $login,
164
- 'author_display_name' => $post['post_author']
165
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
167
  }
168
- }
169
 
170
- /**
171
- * Map old author logins to local user IDs based on decisions made
172
- * in import options form. Can map to an existing user, create a new user
173
- * or falls back to the current user in case of error with either of the previous
174
- */
175
- function get_author_mapping() {
176
- if ( ! isset( $_POST['imported_authors'] ) )
177
- return;
178
-
179
- $create_users = $this->allow_create_users();
180
-
181
- foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
182
- // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
183
- $santized_old_login = sanitize_user( $old_login, true );
184
- $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false;
185
-
186
- if ( ! empty( $_POST['user_map'][$i] ) ) {
187
- $user = get_userdata( intval($_POST['user_map'][$i]) );
188
- if ( isset( $user->ID ) ) {
189
- if ( $old_id )
190
- $this->processed_authors[$old_id] = $user->ID;
191
- $this->author_mapping[$santized_old_login] = $user->ID;
192
- }
193
- } else if ( $create_users ) {
194
- if ( ! empty($_POST['user_new'][$i]) ) {
195
- $user_id = wp_create_user( $_POST['user_new'][$i], wp_generate_password() );
196
- } else if ( $this->version != '1.0' ) {
197
- $user_data = array(
198
- 'user_login' => $old_login,
199
- 'user_pass' => wp_generate_password(),
200
- 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '',
201
- 'display_name' => $this->authors[$old_login]['author_display_name'],
202
- 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '',
203
- 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '',
204
- );
205
- $user_id = wp_insert_user( $user_data );
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
 
208
- if ( ! is_wp_error( $user_id ) ) {
 
209
  if ( $old_id )
210
- $this->processed_authors[$old_id] = $user_id;
211
- $this->author_mapping[$santized_old_login] = $user_id;
212
- } else {
213
- printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html($this->authors[$old_login]['author_display_name']) );
214
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
215
- echo ' ' . $user_id->get_error_message();
216
- echo '<br />';
217
  }
218
  }
219
-
220
- // failsafe: if the user_id was invalid, default to the current user
221
- if ( ! isset( $this->author_mapping[$santized_old_login] ) ) {
222
- if ( $old_id )
223
- $this->processed_authors[$old_id] = (int) get_current_user_id();
224
- $this->author_mapping[$santized_old_login] = (int) get_current_user_id();
225
- }
226
  }
227
- }
228
 
229
- /**
230
- * Create new categories based on import information
231
- *
232
- * Doesn't create a new category if its slug already exists
233
- */
234
- function process_categories() {
235
- $this->categories = apply_filters( 'wp_import_categories', $this->categories );
236
-
237
- if ( empty( $this->categories ) )
238
- return;
239
-
240
- foreach ( $this->categories as $cat ) {
241
- // if the category already exists leave it alone
242
- $term_id = term_exists( $cat['category_nicename'], 'category' );
243
- if ( $term_id ) {
244
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
245
- if ( isset($cat['term_id']) )
246
- $this->processed_terms[intval($cat['term_id'])] = (int) $term_id;
247
- continue;
248
- }
249
 
250
- $category_parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] );
251
- $category_description = isset( $cat['category_description'] ) ? $cat['category_description'] : '';
252
- $catarr = array(
253
- 'category_nicename' => $cat['category_nicename'],
254
- 'category_parent' => $category_parent,
255
- 'cat_name' => $cat['cat_name'],
256
- 'category_description' => $category_description
257
- );
258
- $catarr = wp_slash( $catarr );
259
 
260
- $id = wp_insert_category( $catarr );
261
- if ( ! is_wp_error( $id ) ) {
262
- if ( isset($cat['term_id']) )
263
- $this->processed_terms[intval($cat['term_id'])] = $id;
264
- } else {
265
- printf( __( 'Failed to import category %s', 'wordpress-importer' ), esc_html($cat['category_nicename']) );
266
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
267
- echo ': ' . $id->get_error_message();
268
- echo '<br />';
269
- continue;
 
 
 
270
  }
271
 
272
- $this->process_termmeta( $cat, $id['term_id'] );
273
  }
274
 
275
- unset( $this->categories );
276
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
- /**
279
- * Create new post tags based on import information
280
- *
281
- * Doesn't create a tag if its slug already exists
282
- */
283
- function process_tags() {
284
- $this->tags = apply_filters( 'wp_import_tags', $this->tags );
285
-
286
- if ( empty( $this->tags ) )
287
- return;
288
-
289
- foreach ( $this->tags as $tag ) {
290
- // if the tag already exists leave it alone
291
- $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
292
- if ( $term_id ) {
293
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
294
- if ( isset($tag['term_id']) )
295
- $this->processed_terms[intval($tag['term_id'])] = (int) $term_id;
296
- continue;
297
- }
298
 
299
- $tag = wp_slash( $tag );
300
- $tag_desc = isset( $tag['tag_description'] ) ? $tag['tag_description'] : '';
301
- $tagarr = array( 'slug' => $tag['tag_slug'], 'description' => $tag_desc );
 
 
 
 
 
 
 
 
302
 
303
- $id = wp_insert_term( $tag['tag_name'], 'post_tag', $tagarr );
304
- if ( ! is_wp_error( $id ) ) {
305
- if ( isset($tag['term_id']) )
306
- $this->processed_terms[intval($tag['term_id'])] = $id['term_id'];
307
- } else {
308
- printf( __( 'Failed to import post tag %s', 'wordpress-importer' ), esc_html($tag['tag_name']) );
309
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
310
- echo ': ' . $id->get_error_message();
311
- echo '<br />';
312
- continue;
313
  }
314
 
315
- $this->process_termmeta( $tag, $id['term_id'] );
316
  }
317
 
318
- unset( $this->tags );
319
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
- /**
322
- * Create new terms based on import information
323
- *
324
- * Doesn't create a term its slug already exists
325
- */
326
- function process_terms() {
327
- $this->terms = apply_filters( 'wp_import_terms', $this->terms );
328
-
329
- if ( empty( $this->terms ) )
330
- return;
331
-
332
- foreach ( $this->terms as $term ) {
333
- // if the term already exists in the correct taxonomy leave it alone
334
- $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
335
- if ( $term_id ) {
336
- if ( is_array($term_id) ) $term_id = $term_id['term_id'];
337
- if ( isset($term['term_id']) )
338
- $this->processed_terms[intval($term['term_id'])] = (int) $term_id;
339
- continue;
340
- }
 
341
 
342
- if ( empty( $term['term_parent'] ) ) {
343
- $parent = 0;
344
- } else {
345
- $parent = term_exists( $term['term_parent'], $term['term_taxonomy'] );
346
- if ( is_array( $parent ) ) $parent = $parent['term_id'];
347
  }
348
- $term = wp_slash( $term );
349
- $description = isset( $term['term_description'] ) ? $term['term_description'] : '';
350
- $termarr = array( 'slug' => $term['slug'], 'description' => $description, 'parent' => intval($parent) );
351
-
352
- $id = wp_insert_term( $term['term_name'], $term['term_taxonomy'], $termarr );
353
- if ( ! is_wp_error( $id ) ) {
354
- if ( isset($term['term_id']) )
355
- $this->processed_terms[intval($term['term_id'])] = $id['term_id'];
356
- } else {
357
- printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($term['term_taxonomy']), esc_html($term['term_name']) );
358
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
359
- echo ': ' . $id->get_error_message();
360
- echo '<br />';
361
- continue;
362
- }
363
-
364
- $this->process_termmeta( $term, $id['term_id'] );
365
- }
366
-
367
- unset( $this->terms );
368
- }
369
 
370
- /**
371
- * Add metadata to imported term.
372
- *
373
- * @since 0.6.2
374
- *
375
- * @param array $term Term data from WXR import.
376
- * @param int $term_id ID of the newly created term.
377
- */
378
- protected function process_termmeta( $term, $term_id ) {
379
- if ( ! isset( $term['termmeta'] ) ) {
380
- $term['termmeta'] = array();
381
  }
382
 
383
  /**
384
- * Filters the metadata attached to an imported term.
385
  *
386
  * @since 0.6.2
387
  *
388
- * @param array $termmeta Array of term meta.
389
- * @param int $term_id ID of the newly created term.
390
- * @param array $term Term data from the WXR import.
391
  */
392
- $term['termmeta'] = apply_filters( 'wp_import_term_meta', $term['termmeta'], $term_id, $term );
393
-
394
- if ( empty( $term['termmeta'] ) ) {
395
- return;
396
- }
397
 
398
- foreach ( $term['termmeta'] as $meta ) {
399
  /**
400
- * Filters the meta key for an imported piece of term meta.
401
  *
402
  * @since 0.6.2
403
  *
404
- * @param string $meta_key Meta key.
405
- * @param int $term_id ID of the newly created term.
406
- * @param array $term Term data from the WXR import.
407
  */
408
- $key = apply_filters( 'import_term_meta_key', $meta['key'], $term_id, $term );
409
- if ( ! $key ) {
410
- continue;
411
- }
412
 
413
- // Export gets meta straight from the DB so could have a serialized string
414
- $value = maybe_unserialize( $meta['value'] );
 
415
 
416
- add_term_meta( $term_id, $key, $value );
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
- /**
419
- * Fires after term meta is imported.
420
- *
421
- * @since 0.6.2
422
- *
423
- * @param int $term_id ID of the newly created term.
424
- * @param string $key Meta key.
425
- * @param mixed $value Meta value.
426
- */
427
- do_action( 'import_term_meta', $term_id, $key, $value );
 
 
 
 
 
 
428
  }
429
- }
430
 
431
- /**
432
- * Create new posts based on import information
433
- *
434
- * Posts marked as having a parent which doesn't exist will become top level items.
435
- * Doesn't create a new post if: the post type doesn't exist, the given post ID
436
- * is already noted as imported or a post with the same title and date already exists.
437
- * Note that new/updated terms, comments and meta are imported for the last of the above.
438
- */
439
- function process_posts() {
440
- $this->posts = apply_filters( 'wp_import_posts', $this->posts );
441
-
442
- foreach ( $this->posts as $post ) {
443
- $post = apply_filters( 'wp_import_post_data_raw', $post );
444
-
445
- if ( ! post_type_exists( $post['post_type'] ) ) {
446
- printf( __( 'Failed to import &#8220;%s&#8221;: Invalid post type %s', 'wordpress-importer' ),
447
- esc_html($post['post_title']), esc_html($post['post_type']) );
448
- echo '<br />';
449
- do_action( 'wp_import_post_exists', $post );
450
- continue;
451
- }
452
 
453
- if ( isset( $this->processed_posts[$post['post_id']] ) && ! empty( $post['post_id'] ) )
454
- continue;
455
 
456
- if ( $post['status'] == 'auto-draft' )
457
- continue;
 
 
 
 
 
458
 
459
- if ( 'nav_menu_item' == $post['post_type'] ) {
460
- $this->process_menu_item( $post );
461
- continue;
462
- }
463
 
464
- $post_type_object = get_post_type_object( $post['post_type'] );
 
465
 
466
- $post_exists = post_exists( $post['post_title'], '', $post['post_date'] );
 
 
 
467
 
468
- /**
469
- * Filter ID of the existing post corresponding to post currently importing.
470
- *
471
- * Return 0 to force the post to be imported. Filter the ID to be something else
472
- * to override which existing post is mapped to the imported post.
473
- *
474
- * @see post_exists()
475
- * @since 0.6.2
476
- *
477
- * @param int $post_exists Post ID, or 0 if post did not exist.
478
- * @param array $post The post array to be inserted.
479
- */
480
- $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
481
-
482
- if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
483
- printf( __('%s &#8220;%s&#8221; already exists.', 'wordpress-importer'), $post_type_object->labels->singular_name, esc_html($post['post_title']) );
484
- echo '<br />';
485
- $comment_post_ID = $post_id = $post_exists;
486
- $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
487
- } else {
488
- $post_parent = (int) $post['post_parent'];
489
- if ( $post_parent ) {
490
- // if we already know the parent, map it to the new local ID
491
- if ( isset( $this->processed_posts[$post_parent] ) ) {
492
- $post_parent = $this->processed_posts[$post_parent];
493
- // otherwise record the parent for later
494
- } else {
495
- $this->post_orphans[intval($post['post_id'])] = $post_parent;
496
- $post_parent = 0;
 
 
 
 
 
497
  }
498
- }
499
 
500
- // map the post author
501
- $author = sanitize_user( $post['post_author'], true );
502
- if ( isset( $this->author_mapping[$author] ) )
503
- $author = $this->author_mapping[$author];
504
- else
505
- $author = (int) get_current_user_id();
506
-
507
- $postdata = array(
508
- 'import_id' => $post['post_id'], 'post_author' => $author, 'post_date' => $post['post_date'],
509
- 'post_date_gmt' => $post['post_date_gmt'], 'post_content' => $post['post_content'],
510
- 'post_excerpt' => $post['post_excerpt'], 'post_title' => $post['post_title'],
511
- 'post_status' => $post['status'], 'post_name' => $post['post_name'],
512
- 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'],
513
- 'guid' => $post['guid'], 'post_parent' => $post_parent, 'menu_order' => $post['menu_order'],
514
- 'post_type' => $post['post_type'], 'post_password' => $post['post_password']
515
- );
516
 
517
- $original_post_ID = $post['post_id'];
518
- $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
519
 
520
- $postdata = wp_slash( $postdata );
521
 
522
- if ( 'attachment' == $postdata['post_type'] ) {
523
- $remote_url = ! empty($post['attachment_url']) ? $post['attachment_url'] : $post['guid'];
524
 
525
- // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
526
- // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
527
- $postdata['upload_date'] = $post['post_date'];
528
- if ( isset( $post['postmeta'] ) ) {
529
- foreach( $post['postmeta'] as $meta ) {
530
- if ( $meta['key'] == '_wp_attached_file' ) {
531
- if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) )
532
- $postdata['upload_date'] = $matches[0];
533
- break;
 
534
  }
535
  }
 
 
 
 
 
536
  }
537
 
538
- $comment_post_ID = $post_id = $this->process_attachment( $postdata, $remote_url );
539
- } else {
540
- $comment_post_ID = $post_id = wp_insert_post( $postdata, true );
541
- do_action( 'wp_import_insert_post', $post_id, $original_post_ID, $postdata, $post );
542
- }
 
 
 
543
 
544
- if ( is_wp_error( $post_id ) ) {
545
- printf( __( 'Failed to import %s &#8220;%s&#8221;', 'wordpress-importer' ),
546
- $post_type_object->labels->singular_name, esc_html($post['post_title']) );
547
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
548
- echo ': ' . $post_id->get_error_message();
549
- echo '<br />';
550
- continue;
551
  }
552
 
553
- if ( $post['is_sticky'] == 1 )
554
- stick_post( $post_id );
555
- }
556
-
557
- // map pre-import ID to local ID
558
- $this->processed_posts[intval($post['post_id'])] = (int) $post_id;
559
-
560
- if ( ! isset( $post['terms'] ) )
561
- $post['terms'] = array();
562
-
563
- $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
564
-
565
- // add categories, tags and other terms
566
- if ( ! empty( $post['terms'] ) ) {
567
- $terms_to_set = array();
568
- foreach ( $post['terms'] as $term ) {
569
- // back compat with WXR 1.0 map 'tag' to 'post_tag'
570
- $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
571
- $term_exists = term_exists( $term['slug'], $taxonomy );
572
- $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
573
- if ( ! $term_id ) {
574
- $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
575
- if ( ! is_wp_error( $t ) ) {
576
- $term_id = $t['term_id'];
577
- do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
578
- } else {
579
- printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($taxonomy), esc_html($term['name']) );
580
- if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
581
- echo ': ' . $t->get_error_message();
582
- echo '<br />';
583
- do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
584
- continue;
585
  }
 
586
  }
587
- $terms_to_set[$taxonomy][] = intval( $term_id );
588
- }
589
 
590
- foreach ( $terms_to_set as $tax => $ids ) {
591
- $tt_ids = wp_set_post_terms( $post_id, $ids, $tax );
592
- do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $post );
 
 
593
  }
594
- unset( $post['terms'], $terms_to_set );
595
- }
596
 
597
- if ( ! isset( $post['comments'] ) )
598
- $post['comments'] = array();
599
-
600
- $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
601
-
602
- // add/update comments
603
- if ( ! empty( $post['comments'] ) ) {
604
- $num_comments = 0;
605
- $inserted_comments = array();
606
- foreach ( $post['comments'] as $comment ) {
607
- $comment_id = $comment['comment_id'];
608
- $newcomments[$comment_id]['comment_post_ID'] = $comment_post_ID;
609
- $newcomments[$comment_id]['comment_author'] = $comment['comment_author'];
610
- $newcomments[$comment_id]['comment_author_email'] = $comment['comment_author_email'];
611
- $newcomments[$comment_id]['comment_author_IP'] = $comment['comment_author_IP'];
612
- $newcomments[$comment_id]['comment_author_url'] = $comment['comment_author_url'];
613
- $newcomments[$comment_id]['comment_date'] = $comment['comment_date'];
614
- $newcomments[$comment_id]['comment_date_gmt'] = $comment['comment_date_gmt'];
615
- $newcomments[$comment_id]['comment_content'] = $comment['comment_content'];
616
- $newcomments[$comment_id]['comment_approved'] = $comment['comment_approved'];
617
- $newcomments[$comment_id]['comment_type'] = $comment['comment_type'];
618
- $newcomments[$comment_id]['comment_parent'] = $comment['comment_parent'];
619
- $newcomments[$comment_id]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
620
- if ( isset( $this->processed_authors[$comment['comment_user_id']] ) )
621
- $newcomments[$comment_id]['user_id'] = $this->processed_authors[$comment['comment_user_id']];
622
- }
623
- ksort( $newcomments );
624
-
625
- foreach ( $newcomments as $key => $comment ) {
626
- // if this is a new post we can skip the comment_exists() check
627
- if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
628
- if ( isset( $inserted_comments[$comment['comment_parent']] ) )
629
- $comment['comment_parent'] = $inserted_comments[$comment['comment_parent']];
630
- $comment = wp_filter_comment( $comment );
631
- $inserted_comments[$key] = wp_insert_comment( $comment );
632
- do_action( 'wp_import_insert_comment', $inserted_comments[$key], $comment, $comment_post_ID, $post );
633
-
634
- foreach( $comment['commentmeta'] as $meta ) {
635
- $value = maybe_unserialize( $meta['value'] );
636
- add_comment_meta( $inserted_comments[$key], $meta['key'], $value );
637
- }
638
 
639
- $num_comments++;
 
640
  }
 
641
  }
642
- unset( $newcomments, $inserted_comments, $post['comments'] );
643
- }
644
 
645
- if ( ! isset( $post['postmeta'] ) )
646
- $post['postmeta'] = array();
647
 
648
- $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
649
 
650
- // add/update post meta
651
- if ( ! empty( $post['postmeta'] ) ) {
652
- foreach ( $post['postmeta'] as $meta ) {
653
- $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
654
- $value = false;
655
 
656
- if ( '_edit_last' == $key ) {
657
- if ( isset( $this->processed_authors[intval($meta['value'])] ) )
658
- $value = $this->processed_authors[intval($meta['value'])];
659
- else
660
- $key = false;
661
- }
662
 
663
- if ( $key ) {
664
- // export gets meta straight from the DB so could have a serialized string
665
- if ( ! $value )
666
- $value = maybe_unserialize( $meta['value'] );
667
 
668
- add_post_meta( $post_id, $key, $value );
669
- do_action( 'import_post_meta', $post_id, $key, $value );
670
 
671
- // if the post has a featured image, take note of this in case of remap
672
- if ( '_thumbnail_id' == $key )
673
- $this->featured_images[$post_id] = (int) $value;
 
674
  }
675
  }
676
  }
677
- }
678
 
679
- unset( $this->posts );
680
- }
681
 
682
- /**
683
- * Attempt to create a new menu item from import data
684
- *
685
- * Fails for draft, orphaned menu items and those without an associated nav_menu
686
- * or an invalid nav_menu term. If the post type or term object which the menu item
687
- * represents doesn't exist then the menu item will not be imported (waits until the
688
- * end of the import to retry again before discarding).
689
- *
690
- * @param array $item Menu item details from WXR file
691
- */
692
- function process_menu_item( $item ) {
693
- // skip draft, orphaned menu items
694
- if ( 'draft' == $item['status'] )
695
- return;
696
-
697
- $menu_slug = false;
698
- if ( isset($item['terms']) ) {
699
- // loop through terms, assume first nav_menu term is correct menu
700
- foreach ( $item['terms'] as $term ) {
701
- if ( 'nav_menu' == $term['domain'] ) {
702
- $menu_slug = $term['slug'];
703
- break;
 
704
  }
705
  }
706
- }
707
 
708
- // no nav_menu term associated with this menu item
709
- if ( ! $menu_slug ) {
710
- _e( 'Menu item skipped due to missing menu slug', 'wordpress-importer' );
711
- echo '<br />';
712
- return;
713
- }
714
 
715
- $menu_id = term_exists( $menu_slug, 'nav_menu' );
716
- if ( ! $menu_id ) {
717
- printf( __( 'Menu item skipped due to invalid menu slug: %s', 'wordpress-importer' ), esc_html( $menu_slug ) );
718
- echo '<br />';
719
- return;
720
- } else {
721
- $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
722
- }
723
 
724
- foreach ( $item['postmeta'] as $meta )
725
- ${$meta['key']} = $meta['value'];
726
-
727
- if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[intval($_menu_item_object_id)] ) ) {
728
- $_menu_item_object_id = $this->processed_terms[intval($_menu_item_object_id)];
729
- } else if ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[intval($_menu_item_object_id)] ) ) {
730
- $_menu_item_object_id = $this->processed_posts[intval($_menu_item_object_id)];
731
- } else if ( 'custom' != $_menu_item_type ) {
732
- // associated object is missing or not imported yet, we'll retry later
733
- $this->missing_menu_items[] = $item;
734
- return;
735
- }
 
 
 
 
 
 
 
736
 
737
- if ( isset( $this->processed_menu_items[intval($_menu_item_menu_item_parent)] ) ) {
738
- $_menu_item_menu_item_parent = $this->processed_menu_items[intval($_menu_item_menu_item_parent)];
739
- } else if ( $_menu_item_menu_item_parent ) {
740
- $this->menu_item_orphans[intval($item['post_id'])] = (int) $_menu_item_menu_item_parent;
741
- $_menu_item_menu_item_parent = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
  }
743
 
744
- // wp_update_nav_menu_item expects CSS classes as a space separated string
745
- $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
746
- if ( is_array( $_menu_item_classes ) )
747
- $_menu_item_classes = implode( ' ', $_menu_item_classes );
748
-
749
- $args = array(
750
- 'menu-item-object-id' => $_menu_item_object_id,
751
- 'menu-item-object' => $_menu_item_object,
752
- 'menu-item-parent-id' => $_menu_item_menu_item_parent,
753
- 'menu-item-position' => intval( $item['menu_order'] ),
754
- 'menu-item-type' => $_menu_item_type,
755
- 'menu-item-title' => $item['post_title'],
756
- 'menu-item-url' => $_menu_item_url,
757
- 'menu-item-description' => $item['post_content'],
758
- 'menu-item-attr-title' => $item['post_excerpt'],
759
- 'menu-item-target' => $_menu_item_target,
760
- 'menu-item-classes' => $_menu_item_classes,
761
- 'menu-item-xfn' => $_menu_item_xfn,
762
- 'menu-item-status' => $item['status']
763
- );
764
-
765
- $id = wp_update_nav_menu_item( $menu_id, 0, $args );
766
- if ( $id && ! is_wp_error( $id ) )
767
- $this->processed_menu_items[intval($item['post_id'])] = (int) $id;
768
- }
769
 
770
- /**
771
- * If fetching attachments is enabled then attempt to create a new attachment
772
- *
773
- * @param array $post Attachment post details from WXR
774
- * @param string $url URL to fetch attachment from
775
- * @return int|WP_Error Post ID on success, WP_Error otherwise
776
- */
777
- function process_attachment( $post, $url ) {
778
- if ( ! $this->fetch_attachments )
779
- return new WP_Error( 'attachment_processing_error',
780
- __( 'Fetching attachments is not enabled', 'wordpress-importer' ) );
781
-
782
- // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
783
- if ( preg_match( '|^/[\w\W]+$|', $url ) )
784
- $url = rtrim( $this->base_url, '/' ) . $url;
785
-
786
- $upload = $this->fetch_remote_file( $url, $post );
787
- if ( is_wp_error( $upload ) )
788
- return $upload;
789
 
790
- if ( $info = wp_check_filetype( $upload['file'] ) )
791
- $post['post_mime_type'] = $info['type'];
792
- else
793
- return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'wordpress-importer') );
794
 
795
- $post['guid'] = $upload['url'];
 
 
 
796
 
797
- // as per wp-admin/includes/upload.php
798
- $post_id = wp_insert_attachment( $post, $upload['file'] );
799
- wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
800
 
801
- // remap resized image URLs, works by stripping the extension and remapping the URL stub.
802
- if ( preg_match( '!^image/!', $info['type'] ) ) {
803
- $parts = pathinfo( $url );
804
- $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
805
 
806
- $parts_new = pathinfo( $upload['url'] );
807
- $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
 
 
808
 
809
- $this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
810
- }
811
 
812
- return $post_id;
813
- }
814
 
815
- /**
816
- * Attempt to download a remote file attachment
817
- *
818
- * @param string $url URL of item to fetch
819
- * @param array $post Attachment details
820
- * @return array|WP_Error Local file location details on success, WP_Error otherwise
821
- */
822
- function fetch_remote_file( $url, $post ) {
823
- // extract the file name and extension from the url
824
- $file_name = basename( $url );
825
-
826
- // get placeholder file in the upload dir with a unique, sanitized filename
827
- $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
828
- if ( $upload['error'] )
829
- return new WP_Error( 'upload_dir_error', $upload['error'] );
830
-
831
- // fetch the remote url and write it to the placeholder file
832
- /*EDITED CODE START*/
833
- // fetch the remote url and write it to the placeholder file
834
- $response = wp_remote_get( $url, array(
835
- 'stream' => true,
836
- 'filename' => $upload['file'],
837
- ) );
838
-
839
- // request failed
840
- if ( is_wp_error( $response ) ) {
841
- unlink( $upload['file'] );
842
- return $response;
843
- }
844
-
845
- $code = (int) wp_remote_retrieve_response_code( $response );
846
-
847
- // make sure the fetch was successful
848
- if ( $code !== 200 ) {
849
- unlink( $upload['file'] );
850
- return new WP_Error(
851
- 'import_file_error',
852
- sprintf(
853
- __( 'Remote server returned %1$d %2$s for %3$s', 'wordpress-importer' ),
854
- $code,
855
- get_status_header_desc( $code ),
856
- $url
857
- )
858
- );
859
- }
860
-
861
- $filesize = filesize( $upload['file'] );
862
- $headers = wp_remote_retrieve_headers( $response );
863
- /*EDITED CODE END*/
864
-
865
- if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) {
866
- @unlink( $upload['file'] );
867
- return new WP_Error( 'import_file_error', __('Remote file is incorrect size', 'wordpress-importer') );
868
  }
869
 
870
- if ( 0 == $filesize ) {
871
- @unlink( $upload['file'] );
872
- return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'wordpress-importer') );
873
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874
 
875
- $max_size = (int) $this->max_attachment_size();
876
- if ( ! empty( $max_size ) && $filesize > $max_size ) {
877
- @unlink( $upload['file'] );
878
- return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'wordpress-importer'), size_format($max_size) ) );
879
- }
880
 
881
- // keep track of the old and new urls so we can substitute them later
882
- $this->url_remap[$url] = $upload['url'];
883
- $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed?
884
- // keep track of the destination if the remote url is redirected somewhere else
885
- if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url )
886
- $this->url_remap[$headers['x-final-location']] = $upload['url'];
887
 
888
- return $upload;
889
- }
 
 
 
 
890
 
891
- /**
892
- * Attempt to associate posts and menu items with previously missing parents
893
- *
894
- * An imported post's parent may not have been imported when it was first created
895
- * so try again. Similarly for child menu items and menu items which were missing
896
- * the object (e.g. post) they represent in the menu
897
- */
898
- function backfill_parents() {
899
- global $wpdb;
900
-
901
- // find parents for post orphans
902
- foreach ( $this->post_orphans as $child_id => $parent_id ) {
903
- $local_child_id = $local_parent_id = false;
904
- if ( isset( $this->processed_posts[$child_id] ) )
905
- $local_child_id = $this->processed_posts[$child_id];
906
- if ( isset( $this->processed_posts[$parent_id] ) )
907
- $local_parent_id = $this->processed_posts[$parent_id];
908
-
909
- if ( $local_child_id && $local_parent_id )
910
- $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
911
  }
912
 
913
- // all other posts/terms are imported, retry menu items with missing associated object
914
- $missing_menu_items = $this->missing_menu_items;
915
- foreach ( $missing_menu_items as $item )
916
- $this->process_menu_item( $item );
917
-
918
- // find parents for menu item orphans
919
- foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
920
- $local_child_id = $local_parent_id = 0;
921
- if ( isset( $this->processed_menu_items[$child_id] ) )
922
- $local_child_id = $this->processed_menu_items[$child_id];
923
- if ( isset( $this->processed_menu_items[$parent_id] ) )
924
- $local_parent_id = $this->processed_menu_items[$parent_id];
925
-
926
- if ( $local_child_id && $local_parent_id )
927
- update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
928
  }
929
- }
930
 
931
- /**
932
- * Use stored mapping information to update old attachment URLs
933
- */
934
- function backfill_attachment_urls() {
935
- global $wpdb;
936
- // make sure we do the longest urls first, in case one is a substring of another
937
- uksort( $this->url_remap, array(&$this, 'cmpr_strlen') );
938
-
939
- foreach ( $this->url_remap as $from_url => $to_url ) {
940
- // remap urls in post_content
941
- $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );
942
- // remap enclosure urls
943
- $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) );
 
944
  }
945
- }
946
 
947
- /**
948
- * Update _thumbnail_id meta to new, imported attachment IDs
949
- */
950
- function remap_featured_images() {
951
- // cycle through posts that have a featured image
952
- foreach ( $this->featured_images as $post_id => $value ) {
953
- if ( isset( $this->processed_posts[$value] ) ) {
954
- $new_id = $this->processed_posts[$value];
955
- // only update if there's a difference
956
- if ( $new_id != $value )
957
- update_post_meta( $post_id, '_thumbnail_id', $new_id );
 
958
  }
959
  }
960
- }
961
 
962
- /**
963
- * Parse a WXR file
964
- *
965
- * @param string $file Path to WXR file for parsing
966
- * @return array Information gathered from the WXR file
967
- */
968
- function parse( $file ) {
969
- $parser = new Acme_Demo_Setup_WXR_Parser();
970
- return $parser->parse( $file );
971
- }
972
 
973
 
974
- /**
975
- * Decide if the given meta key maps to information we will want to import
976
- *
977
- * @param string $key The meta key to check
978
- * @return string|bool The key if we do want to import, false if not
979
- */
980
- function is_valid_meta_key( $key ) {
981
- // skip attachment metadata since we'll regenerate it from scratch
982
- // skip _edit_lock as not relevant for import
983
- if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) )
984
- return false;
985
- return $key;
986
- }
987
 
988
- /**
989
- * Decide whether or not the importer is allowed to create users.
990
- * Default is true, can be filtered via import_allow_create_users
991
- *
992
- * @return bool True if creating users is allowed
993
- */
994
- function allow_create_users() {
995
- return apply_filters( 'import_allow_create_users', true );
996
- }
997
 
998
 
999
- /**
1000
- * Decide what the maximum file size for downloaded attachments is.
1001
- * Default is 0 (unlimited), can be filtered via import_attachment_size_limit
1002
- *
1003
- * @return int Maximum attachment file size to import
1004
- */
1005
- function max_attachment_size() {
1006
- return apply_filters( 'import_attachment_size_limit', 0 );
1007
- }
1008
 
1009
- /**
1010
- * Added to http_request_timeout filter to force timeout at 60 seconds during import
1011
- * @return int 300
1012
- */
1013
- function bump_request_timeout( $val ) {
1014
- return 300;
1015
- }
1016
 
1017
- // return the difference in length between two strings
1018
- function cmpr_strlen( $a, $b ) {
1019
- return strlen($b) - strlen($a);
 
1020
  }
1021
- }
1022
 
1023
  } // class_exists( 'Acme_Demo_Setup_Wp_Import' )
24
  * Renaming WP_Import to Acme_Demo_Setup_Wp_Import
25
  */
26
  if ( class_exists( 'WP_Importer' ) ) {
27
+ class Acme_Demo_Setup_Wp_Import extends WP_Importer {
28
+ var $max_wxr_version = 1.2; // max. supported WXR version
29
+
30
+ var $id; // WXR attachment ID
31
+
32
+ // information to import from WXR file
33
+ var $version;
34
+ var $authors = array();
35
+ var $posts = array();
36
+ var $terms = array();
37
+ var $categories = array();
38
+ var $tags = array();
39
+ var $base_url = '';
40
+
41
+ // mappings from old information to new
42
+ var $processed_authors = array();
43
+ var $author_mapping = array();
44
+ var $processed_terms = array();
45
+ var $processed_posts = array();
46
+ var $post_orphans = array();
47
+ var $processed_menu_items = array();
48
+ var $menu_item_orphans = array();
49
+ var $missing_menu_items = array();
50
+
51
+ var $fetch_attachments = false;
52
+ var $url_remap = array();
53
+ var $featured_images = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ /**
56
+ * The main controller for the actual import stage.
57
+ *
58
+ * @param string $file Path to the WXR file for importing
59
+ */
60
+ function import( $file ) {
61
+
62
+ add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) );
63
+ add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
64
+
65
+ $this->import_start( $file );
66
+
67
+ $this->get_author_mapping();
68
 
69
+ wp_suspend_cache_invalidation( true );
70
+ $this->process_categories();
71
+ $this->process_tags();
72
+ $this->process_terms();
73
+ $this->process_posts();
74
+ wp_suspend_cache_invalidation( false );
75
 
76
+ // update incorrect/missing information in the DB
77
+ $this->backfill_parents();
78
+ $this->backfill_attachment_urls();
79
+ $this->remap_featured_images();
80
+
81
+ $this->import_end();
82
  }
83
 
84
+ /**
85
+ * Parses the WXR file and prepares us for the task of processing parsed data
86
+ *
87
+ * @param string $file Path to the WXR file for importing
88
+ */
89
+ function import_start( $file ) {
90
+
91
+ if ( ! is_file($file) ) {
92
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
93
+ echo __( 'The file does not exist, please try again.', 'wordpress-importer' ) . '</p>';
94
+ die();
95
+ }
96
 
97
+ $import_data = $this->parse( $file );
 
98
 
99
+ if ( is_wp_error( $import_data ) ) {
100
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'wordpress-importer' ) . '</strong><br />';
101
+ echo esc_html( $import_data->get_error_message() ) . '</p>';
102
+ die();
103
+ }
104
 
105
+ $this->version = $import_data['version'];
106
+ $this->get_authors_from_import( $import_data );
107
+ $this->posts = $import_data['posts'];
108
+ $this->terms = $import_data['terms'];
109
+ $this->categories = $import_data['categories'];
110
+ $this->tags = $import_data['tags'];
111
+ $this->base_url = esc_url( $import_data['base_url'] );
112
 
113
+ wp_defer_term_counting( true );
114
+ wp_defer_comment_counting( true );
115
+
116
+ do_action( 'import_start' );
117
  }
118
 
119
+ /**
120
+ * Performs post-import cleanup of files and the cache
121
+ */
122
+ function import_end() {
123
+ wp_import_cleanup( $this->id );
124
 
125
+ wp_cache_flush();
126
+ foreach ( get_taxonomies() as $tax ) {
127
+ delete_option( "{$tax}_children" );
128
+ _get_term_hierarchy( $tax );
129
+ }
130
 
131
+ wp_defer_term_counting( false );
132
+ wp_defer_comment_counting( false );
133
 
134
+ echo '<p>' . __( 'Remember to update the passwords and roles of imported users.', 'wordpress-importer' ) . '</p>';
135
 
136
+ do_action( 'import_end' );
137
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
+
140
+ /**
141
+ * Retrieve authors from parsed WXR data
142
+ *
143
+ * Uses the provided author information from WXR 1.1 files
144
+ * or extracts info from each post for WXR 1.0 files
145
+ *
146
+ * @param array $import_data Data returned by a WXR parser
147
+ */
148
+ function get_authors_from_import( $import_data ) {
149
+ if ( ! empty( $import_data['authors'] ) ) {
150
+ $this->authors = $import_data['authors'];
151
+ // no author information, grab it from the posts
152
+ } else {
153
+ foreach ( $import_data['posts'] as $post ) {
154
+ $login = sanitize_user( $post['post_author'], true );
155
+ if ( empty( $login ) ) {
156
+ printf( __( 'Failed to import author %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html( $post['post_author'] ) );
157
+ echo '<br />';
158
+ continue;
159
+ }
160
+
161
+ if ( ! isset($this->authors[$login]) )
162
+ $this->authors[$login] = array(
163
+ 'author_login' => $login,
164
+ 'author_display_name' => $post['post_author']
165
+ );
166
+ }
167
  }
168
  }
 
169
 
170
+ /**
171
+ * Map old author logins to local user IDs based on decisions made
172
+ * in import options form. Can map to an existing user, create a new user
173
+ * or falls back to the current user in case of error with either of the previous
174
+ */
175
+ function get_author_mapping() {
176
+ if ( ! isset( $_POST['imported_authors'] ) )
177
+ return;
178
+
179
+ $create_users = $this->allow_create_users();
180
+
181
+ foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
182
+ // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
183
+ $santized_old_login = sanitize_user( $old_login, true );
184
+ $old_id = isset( $this->authors[$old_login]['author_id'] ) ? intval($this->authors[$old_login]['author_id']) : false;
185
+
186
+ if ( ! empty( $_POST['user_map'][$i] ) ) {
187
+ $user = get_userdata( intval($_POST['user_map'][$i]) );
188
+ if ( isset( $user->ID ) ) {
189
+ if ( $old_id )
190
+ $this->processed_authors[$old_id] = $user->ID;
191
+ $this->author_mapping[$santized_old_login] = $user->ID;
192
+ }
193
+ } else if ( $create_users ) {
194
+ if ( ! empty($_POST['user_new'][$i]) ) {
195
+ $user_id = wp_create_user( $_POST['user_new'][$i], wp_generate_password() );
196
+ } else if ( $this->version != '1.0' ) {
197
+ $user_data = array(
198
+ 'user_login' => $old_login,
199
+ 'user_pass' => wp_generate_password(),
200
+ 'user_email' => isset( $this->authors[$old_login]['author_email'] ) ? $this->authors[$old_login]['author_email'] : '',
201
+ 'display_name' => $this->authors[$old_login]['author_display_name'],
202
+ 'first_name' => isset( $this->authors[$old_login]['author_first_name'] ) ? $this->authors[$old_login]['author_first_name'] : '',
203
+ 'last_name' => isset( $this->authors[$old_login]['author_last_name'] ) ? $this->authors[$old_login]['author_last_name'] : '',
204
+ );
205
+ $user_id = wp_insert_user( $user_data );
206
+ }
207
+
208
+ if ( ! is_wp_error( $user_id ) ) {
209
+ if ( $old_id )
210
+ $this->processed_authors[$old_id] = $user_id;
211
+ $this->author_mapping[$santized_old_login] = $user_id;
212
+ } else {
213
+ printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'wordpress-importer' ), esc_html($this->authors[$old_login]['author_display_name']) );
214
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
215
+ echo ' ' . $user_id->get_error_message();
216
+ echo '<br />';
217
+ }
218
  }
219
 
220
+ // failsafe: if the user_id was invalid, default to the current user
221
+ if ( ! isset( $this->author_mapping[$santized_old_login] ) ) {
222
  if ( $old_id )
223
+ $this->processed_authors[$old_id] = (int) get_current_user_id();
224
+ $this->author_mapping[$santized_old_login] = (int) get_current_user_id();
 
 
 
 
 
225
  }
226
  }
 
 
 
 
 
 
 
227
  }
 
228
 
229
+ /**
230
+ * Create new categories based on import information
231
+ *
232
+ * Doesn't create a new category if its slug already exists
233
+ */
234
+ function process_categories() {
235
+ $this->categories = apply_filters( 'wp_import_categories', $this->categories );
236
+
237
+ if ( empty( $this->categories ) )
238
+ return;
239
+
240
+ foreach ( $this->categories as $cat ) {
241
+ // if the category already exists leave it alone
242
+ $term_id = term_exists( $cat['category_nicename'], 'category' );
243
+ if ( $term_id ) {
244
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
245
+ if ( isset($cat['term_id']) )
246
+ $this->processed_terms[intval($cat['term_id'])] = (int) $term_id;
247
+ continue;
248
+ }
249
 
250
+ $category_parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] );
251
+ $category_description = isset( $cat['category_description'] ) ? $cat['category_description'] : '';
252
+ $catarr = array(
253
+ 'category_nicename' => $cat['category_nicename'],
254
+ 'category_parent' => $category_parent,
255
+ 'cat_name' => $cat['cat_name'],
256
+ 'category_description' => $category_description
257
+ );
258
+ $catarr = wp_slash( $catarr );
259
 
260
+ $id = wp_insert_category( $catarr );
261
+ if ( ! is_wp_error( $id ) ) {
262
+ if ( isset($cat['term_id']) )
263
+ $this->processed_terms[intval($cat['term_id'])] = $id;
264
+ } else {
265
+ printf( __( 'Failed to import category %s', 'wordpress-importer' ), esc_html($cat['category_nicename']) );
266
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
267
+ echo ': ' . $id->get_error_message();
268
+ echo '<br />';
269
+ continue;
270
+ }
271
+
272
+ $this->process_termmeta( $cat, $id['term_id'] );
273
  }
274
 
275
+ unset( $this->categories );
276
  }
277
 
278
+ /**
279
+ * Create new post tags based on import information
280
+ *
281
+ * Doesn't create a tag if its slug already exists
282
+ */
283
+ function process_tags() {
284
+ $this->tags = apply_filters( 'wp_import_tags', $this->tags );
285
+
286
+ if ( empty( $this->tags ) )
287
+ return;
288
+
289
+ foreach ( $this->tags as $tag ) {
290
+ // if the tag already exists leave it alone
291
+ $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
292
+ if ( $term_id ) {
293
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
294
+ if ( isset($tag['term_id']) )
295
+ $this->processed_terms[intval($tag['term_id'])] = (int) $term_id;
296
+ continue;
297
+ }
298
 
299
+ $tag = wp_slash( $tag );
300
+ $tag_desc = isset( $tag['tag_description'] ) ? $tag['tag_description'] : '';
301
+ $tagarr = array( 'slug' => $tag['tag_slug'], 'description' => $tag_desc );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
+ $id = wp_insert_term( $tag['tag_name'], 'post_tag', $tagarr );
304
+ if ( ! is_wp_error( $id ) ) {
305
+ if ( isset($tag['term_id']) )
306
+ $this->processed_terms[intval($tag['term_id'])] = $id['term_id'];
307
+ } else {
308
+ printf( __( 'Failed to import post tag %s', 'wordpress-importer' ), esc_html($tag['tag_name']) );
309
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
310
+ echo ': ' . $id->get_error_message();
311
+ echo '<br />';
312
+ continue;
313
+ }
314
 
315
+ $this->process_termmeta( $tag, $id['term_id'] );
 
 
 
 
 
 
 
 
 
316
  }
317
 
318
+ unset( $this->tags );
319
  }
320
 
321
+ /**
322
+ * Create new terms based on import information
323
+ *
324
+ * Doesn't create a term its slug already exists
325
+ */
326
+ function process_terms() {
327
+ $this->terms = apply_filters( 'wp_import_terms', $this->terms );
328
+
329
+ if ( empty( $this->terms ) )
330
+ return;
331
+
332
+ foreach ( $this->terms as $term ) {
333
+ // if the term already exists in the correct taxonomy leave it alone
334
+ $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
335
+ if ( $term_id ) {
336
+ if ( is_array($term_id) ) $term_id = $term_id['term_id'];
337
+ if ( isset($term['term_id']) )
338
+ $this->processed_terms[intval($term['term_id'])] = (int) $term_id;
339
+ continue;
340
+ }
341
 
342
+ if ( empty( $term['term_parent'] ) ) {
343
+ $parent = 0;
344
+ } else {
345
+ $parent = term_exists( $term['term_parent'], $term['term_taxonomy'] );
346
+ if ( is_array( $parent ) ) $parent = $parent['term_id'];
347
+ }
348
+ $term = wp_slash( $term );
349
+ $description = isset( $term['term_description'] ) ? $term['term_description'] : '';
350
+ $termarr = array( 'slug' => $term['slug'], 'description' => $description, 'parent' => intval($parent) );
351
+
352
+ $id = wp_insert_term( $term['term_name'], $term['term_taxonomy'], $termarr );
353
+ if ( ! is_wp_error( $id ) ) {
354
+ if ( isset($term['term_id']) )
355
+ $this->processed_terms[intval($term['term_id'])] = $id['term_id'];
356
+ } else {
357
+ printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($term['term_taxonomy']), esc_html($term['term_name']) );
358
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
359
+ echo ': ' . $id->get_error_message();
360
+ echo '<br />';
361
+ continue;
362
+ }
363
 
364
+ $this->process_termmeta( $term, $id['term_id'] );
 
 
 
 
365
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
+ unset( $this->terms );
 
 
 
 
 
 
 
 
 
 
368
  }
369
 
370
  /**
371
+ * Add metadata to imported term.
372
  *
373
  * @since 0.6.2
374
  *
375
+ * @param array $term Term data from WXR import.
376
+ * @param int $term_id ID of the newly created term.
 
377
  */
378
+ protected function process_termmeta( $term, $term_id ) {
379
+ if ( ! isset( $term['termmeta'] ) ) {
380
+ $term['termmeta'] = array();
381
+ }
 
382
 
 
383
  /**
384
+ * Filters the metadata attached to an imported term.
385
  *
386
  * @since 0.6.2
387
  *
388
+ * @param array $termmeta Array of term meta.
389
+ * @param int $term_id ID of the newly created term.
390
+ * @param array $term Term data from the WXR import.
391
  */
392
+ $term['termmeta'] = apply_filters( 'wp_import_term_meta', $term['termmeta'], $term_id, $term );
 
 
 
393
 
394
+ if ( empty( $term['termmeta'] ) ) {
395
+ return;
396
+ }
397
 
398
+ foreach ( $term['termmeta'] as $meta ) {
399
+ /**
400
+ * Filters the meta key for an imported piece of term meta.
401
+ *
402
+ * @since 0.6.2
403
+ *
404
+ * @param string $meta_key Meta key.
405
+ * @param int $term_id ID of the newly created term.
406
+ * @param array $term Term data from the WXR import.
407
+ */
408
+ $key = apply_filters( 'import_term_meta_key', $meta['key'], $term_id, $term );
409
+ if ( ! $key ) {
410
+ continue;
411
+ }
412
 
413
+ // Export gets meta straight from the DB so could have a serialized string
414
+ $value = maybe_unserialize( $meta['value'] );
415
+
416
+ add_term_meta( $term_id, $key, $value );
417
+
418
+ /**
419
+ * Fires after term meta is imported.
420
+ *
421
+ * @since 0.6.2
422
+ *
423
+ * @param int $term_id ID of the newly created term.
424
+ * @param string $key Meta key.
425
+ * @param mixed $value Meta value.
426
+ */
427
+ do_action( 'import_term_meta', $term_id, $key, $value );
428
+ }
429
  }
 
430
 
431
+ /**
432
+ * Create new posts based on import information
433
+ *
434
+ * Posts marked as having a parent which doesn't exist will become top level items.
435
+ * Doesn't create a new post if: the post type doesn't exist, the given post ID
436
+ * is already noted as imported or a post with the same title and date already exists.
437
+ * Note that new/updated terms, comments and meta are imported for the last of the above.
438
+ */
439
+ function process_posts() {
440
+ $this->posts = apply_filters( 'wp_import_posts', $this->posts );
 
 
 
 
 
 
 
 
 
 
 
441
 
442
+ foreach ( $this->posts as $post ) {
443
+ $post = apply_filters( 'wp_import_post_data_raw', $post );
444
 
445
+ if ( ! post_type_exists( $post['post_type'] ) ) {
446
+ printf( __( 'Failed to import &#8220;%s&#8221;: Invalid post type %s', 'wordpress-importer' ),
447
+ esc_html($post['post_title']), esc_html($post['post_type']) );
448
+ echo '<br />';
449
+ do_action( 'wp_import_post_exists', $post );
450
+ continue;
451
+ }
452
 
453
+ if ( isset( $this->processed_posts[$post['post_id']] ) && ! empty( $post['post_id'] ) )
454
+ continue;
 
 
455
 
456
+ if ( $post['status'] == 'auto-draft' )
457
+ continue;
458
 
459
+ if ( 'nav_menu_item' == $post['post_type'] ) {
460
+ $this->process_menu_item( $post );
461
+ continue;
462
+ }
463
 
464
+ $post_type_object = get_post_type_object( $post['post_type'] );
465
+
466
+ $post_exists = post_exists( $post['post_title'], '', $post['post_date'] );
467
+
468
+ /**
469
+ * Filter ID of the existing post corresponding to post currently importing.
470
+ *
471
+ * Return 0 to force the post to be imported. Filter the ID to be something else
472
+ * to override which existing post is mapped to the imported post.
473
+ *
474
+ * @see post_exists()
475
+ * @since 0.6.2
476
+ *
477
+ * @param int $post_exists Post ID, or 0 if post did not exist.
478
+ * @param array $post The post array to be inserted.
479
+ */
480
+ $post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );
481
+
482
+ if ( $post_exists && get_post_type( $post_exists ) == $post['post_type'] ) {
483
+ printf( __('%s &#8220;%s&#8221; already exists.', 'wordpress-importer'), $post_type_object->labels->singular_name, esc_html($post['post_title']) );
484
+ echo '<br />';
485
+ $comment_post_ID = $post_id = $post_exists;
486
+ $this->processed_posts[ intval( $post['post_id'] ) ] = intval( $post_exists );
487
+ } else {
488
+ $post_parent = (int) $post['post_parent'];
489
+ if ( $post_parent ) {
490
+ // if we already know the parent, map it to the new local ID
491
+ if ( isset( $this->processed_posts[$post_parent] ) ) {
492
+ $post_parent = $this->processed_posts[$post_parent];
493
+ // otherwise record the parent for later
494
+ } else {
495
+ $this->post_orphans[intval($post['post_id'])] = $post_parent;
496
+ $post_parent = 0;
497
+ }
498
  }
 
499
 
500
+ // map the post author
501
+ $author = sanitize_user( $post['post_author'], true );
502
+ if ( isset( $this->author_mapping[$author] ) )
503
+ $author = $this->author_mapping[$author];
504
+ else
505
+ $author = (int) get_current_user_id();
506
+
507
+ $postdata = array(
508
+ 'import_id' => $post['post_id'], 'post_author' => $author, 'post_date' => $post['post_date'],
509
+ 'post_date_gmt' => $post['post_date_gmt'], 'post_content' => $post['post_content'],
510
+ 'post_excerpt' => $post['post_excerpt'], 'post_title' => $post['post_title'],
511
+ 'post_status' => $post['status'], 'post_name' => $post['post_name'],
512
+ 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'],
513
+ 'guid' => $post['guid'], 'post_parent' => $post_parent, 'menu_order' => $post['menu_order'],
514
+ 'post_type' => $post['post_type'], 'post_password' => $post['post_password']
515
+ );
516
 
517
+ $original_post_ID = $post['post_id'];
518
+ $postdata = apply_filters( 'wp_import_post_data_processed', $postdata, $post );
519
 
520
+ $postdata = wp_slash( $postdata );
521
 
522
+ if ( 'attachment' == $postdata['post_type'] ) {
523
+ $remote_url = ! empty($post['attachment_url']) ? $post['attachment_url'] : $post['guid'];
524
 
525
+ // try to use _wp_attached file for upload folder placement to ensure the same location as the export site
526
+ // e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
527
+ $postdata['upload_date'] = $post['post_date'];
528
+ if ( isset( $post['postmeta'] ) ) {
529
+ foreach( $post['postmeta'] as $meta ) {
530
+ if ( $meta['key'] == '_wp_attached_file' ) {
531
+ if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) )
532
+ $postdata['upload_date'] = $matches[0];
533
+ break;
534
+ }
535
  }
536
  }
537
+
538
+ $comment_post_ID = $post_id = $this->process_attachment( $postdata, $remote_url );
539
+ } else {
540
+ $comment_post_ID = $post_id = wp_insert_post( $postdata, true );
541
+ do_action( 'wp_import_insert_post', $post_id, $original_post_ID, $postdata, $post );
542
  }
543
 
544
+ if ( is_wp_error( $post_id ) ) {
545
+ printf( __( 'Failed to import %s &#8220;%s&#8221;', 'wordpress-importer' ),
546
+ $post_type_object->labels->singular_name, esc_html($post['post_title']) );
547
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
548
+ echo ': ' . $post_id->get_error_message();
549
+ echo '<br />';
550
+ continue;
551
+ }
552
 
553
+ if ( $post['is_sticky'] == 1 )
554
+ stick_post( $post_id );
 
 
 
 
 
555
  }
556
 
557
+ // map pre-import ID to local ID
558
+ $this->processed_posts[intval($post['post_id'])] = (int) $post_id;
559
+
560
+ if ( ! isset( $post['terms'] ) )
561
+ $post['terms'] = array();
562
+
563
+ $post['terms'] = apply_filters( 'wp_import_post_terms', $post['terms'], $post_id, $post );
564
+
565
+ // add categories, tags and other terms
566
+ if ( ! empty( $post['terms'] ) ) {
567
+ $terms_to_set = array();
568
+ foreach ( $post['terms'] as $term ) {
569
+ // back compat with WXR 1.0 map 'tag' to 'post_tag'
570
+ $taxonomy = ( 'tag' == $term['domain'] ) ? 'post_tag' : $term['domain'];
571
+ $term_exists = term_exists( $term['slug'], $taxonomy );
572
+ $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : $term_exists;
573
+ if ( ! $term_id ) {
574
+ $t = wp_insert_term( $term['name'], $taxonomy, array( 'slug' => $term['slug'] ) );
575
+ if ( ! is_wp_error( $t ) ) {
576
+ $term_id = $t['term_id'];
577
+ do_action( 'wp_import_insert_term', $t, $term, $post_id, $post );
578
+ } else {
579
+ printf( __( 'Failed to import %s %s', 'wordpress-importer' ), esc_html($taxonomy), esc_html($term['name']) );
580
+ if ( defined('IMPORT_DEBUG') && IMPORT_DEBUG )
581
+ echo ': ' . $t->get_error_message();
582
+ echo '<br />';
583
+ do_action( 'wp_import_insert_term_failed', $t, $term, $post_id, $post );
584
+ continue;
585
+ }
 
 
 
586
  }
587
+ $terms_to_set[$taxonomy][] = intval( $term_id );
588
  }
 
 
589
 
590
+ foreach ( $terms_to_set as $tax => $ids ) {
591
+ $tt_ids = wp_set_post_terms( $post_id, $ids, $tax );
592
+ do_action( 'wp_import_set_post_terms', $tt_ids, $ids, $tax, $post_id, $post );
593
+ }
594
+ unset( $post['terms'], $terms_to_set );
595
  }
 
 
596
 
597
+ if ( ! isset( $post['comments'] ) )
598
+ $post['comments'] = array();
599
+
600
+ $post['comments'] = apply_filters( 'wp_import_post_comments', $post['comments'], $post_id, $post );
601
+
602
+ // add/update comments
603
+ if ( ! empty( $post['comments'] ) ) {
604
+ $num_comments = 0;
605
+ $inserted_comments = array();
606
+ foreach ( $post['comments'] as $comment ) {
607
+ $comment_id = $comment['comment_id'];
608
+ $newcomments[$comment_id]['comment_post_ID'] = $comment_post_ID;
609
+ $newcomments[$comment_id]['comment_author'] = $comment['comment_author'];
610
+ $newcomments[$comment_id]['comment_author_email'] = $comment['comment_author_email'];
611
+ $newcomments[$comment_id]['comment_author_IP'] = $comment['comment_author_IP'];
612
+ $newcomments[$comment_id]['comment_author_url'] = $comment['comment_author_url'];
613
+ $newcomments[$comment_id]['comment_date'] = $comment['comment_date'];
614
+ $newcomments[$comment_id]['comment_date_gmt'] = $comment['comment_date_gmt'];
615
+ $newcomments[$comment_id]['comment_content'] = $comment['comment_content'];
616
+ $newcomments[$comment_id]['comment_approved'] = $comment['comment_approved'];
617
+ $newcomments[$comment_id]['comment_type'] = $comment['comment_type'];
618
+ $newcomments[$comment_id]['comment_parent'] = $comment['comment_parent'];
619
+ $newcomments[$comment_id]['commentmeta'] = isset( $comment['commentmeta'] ) ? $comment['commentmeta'] : array();
620
+ if ( isset( $this->processed_authors[$comment['comment_user_id']] ) )
621
+ $newcomments[$comment_id]['user_id'] = $this->processed_authors[$comment['comment_user_id']];
622
+ }
623
+ ksort( $newcomments );
624
+
625
+ foreach ( $newcomments as $key => $comment ) {
626
+ // if this is a new post we can skip the comment_exists() check
627
+ if ( ! $post_exists || ! comment_exists( $comment['comment_author'], $comment['comment_date'] ) ) {
628
+ if ( isset( $inserted_comments[$comment['comment_parent']] ) )
629
+ $comment['comment_parent'] = $inserted_comments[$comment['comment_parent']];
630
+ $comment = wp_filter_comment( $comment );
631
+ $inserted_comments[$key] = wp_insert_comment( $comment );
632
+ do_action( 'wp_import_insert_comment', $inserted_comments[$key], $comment, $comment_post_ID, $post );
633
+
634
+ foreach( $comment['commentmeta'] as $meta ) {
635
+ $value = maybe_unserialize( $meta['value'] );
636
+ add_comment_meta( $inserted_comments[$key], $meta['key'], $value );
637
+ }
638
 
639
+ $num_comments++;
640
+ }
641
  }
642
+ unset( $newcomments, $inserted_comments, $post['comments'] );
643
  }
 
 
644
 
645
+ if ( ! isset( $post['postmeta'] ) )
646
+ $post['postmeta'] = array();
647
 
648
+ $post['postmeta'] = apply_filters( 'wp_import_post_meta', $post['postmeta'], $post_id, $post );
649
 
650
+ // add/update post meta
651
+ if ( ! empty( $post['postmeta'] ) ) {
652
+ foreach ( $post['postmeta'] as $meta ) {
653
+ $key = apply_filters( 'import_post_meta_key', $meta['key'], $post_id, $post );
654
+ $value = false;
655
 
656
+ if ( '_edit_last' == $key ) {
657
+ if ( isset( $this->processed_authors[intval($meta['value'])] ) )
658
+ $value = $this->processed_authors[intval($meta['value'])];
659
+ else
660
+ $key = false;
661
+ }
662
 
663
+ if ( $key ) {
664
+ // export gets meta straight from the DB so could have a serialized string
665
+ if ( ! $value )
666
+ $value = maybe_unserialize( $meta['value'] );
667
 
668
+ add_post_meta( $post_id, $key, $value );
669
+ do_action( 'import_post_meta', $post_id, $key, $value );
670
 
671
+ // if the post has a featured image, take note of this in case of remap
672
+ if ( '_thumbnail_id' == $key )
673
+ $this->featured_images[$post_id] = (int) $value;
674
+ }
675
  }
676
  }
677
  }
 
678
 
679
+ unset( $this->posts );
680
+ }
681
 
682
+ /**
683
+ * Attempt to create a new menu item from import data
684
+ *
685
+ * Fails for draft, orphaned menu items and those without an associated nav_menu
686
+ * or an invalid nav_menu term. If the post type or term object which the menu item
687
+ * represents doesn't exist then the menu item will not be imported (waits until the
688
+ * end of the import to retry again before discarding).
689
+ *
690
+ * @param array $item Menu item details from WXR file
691
+ */
692
+ function process_menu_item( $item ) {
693
+ // skip draft, orphaned menu items
694
+ if ( 'draft' == $item['status'] )
695
+ return;
696
+
697
+ $menu_slug = false;
698
+ if ( isset($item['terms']) ) {
699
+ // loop through terms, assume first nav_menu term is correct menu
700
+ foreach ( $item['terms'] as $term ) {
701
+ if ( 'nav_menu' == $term['domain'] ) {
702
+ $menu_slug = $term['slug'];
703
+ break;
704
+ }
705
  }
706
  }
 
707
 
708
+ // no nav_menu term associated with this menu item
709
+ if ( ! $menu_slug ) {
710
+ _e( 'Menu item skipped due to missing menu slug', 'wordpress-importer' );
711
+ echo '<br />';
712
+ return;
713
+ }
714
 
715
+ $menu_id = term_exists( $menu_slug, 'nav_menu' );
716
+ if ( ! $menu_id ) {
717
+ printf( __( 'Menu item skipped due to invalid menu slug: %s', 'wordpress-importer' ), esc_html( $menu_slug ) );
718
+ echo '<br />';
719
+ return;
720
+ } else {
721
+ $menu_id = is_array( $menu_id ) ? $menu_id['term_id'] : $menu_id;
722
+ }
723
 
724
+ foreach ( $item['postmeta'] as $meta )
725
+ ${$meta['key']} = $meta['value'];
726
+
727
+ if ( 'taxonomy' == $_menu_item_type && isset( $this->processed_terms[intval($_menu_item_object_id)] ) ) {
728
+ $_menu_item_object_id = $this->processed_terms[intval($_menu_item_object_id)];
729
+ } else if ( 'post_type' == $_menu_item_type && isset( $this->processed_posts[intval($_menu_item_object_id)] ) ) {
730
+ $_menu_item_object_id = $this->processed_posts[intval($_menu_item_object_id)];
731
+ } else if ( 'custom' != $_menu_item_type ) {
732
+ // associated object is missing or not imported yet, we'll retry later
733
+ $this->missing_menu_items[] = $item;
734
+ return;
735
+ }
736
+
737
+ if ( isset( $this->processed_menu_items[intval($_menu_item_menu_item_parent)] ) ) {
738
+ $_menu_item_menu_item_parent = $this->processed_menu_items[intval($_menu_item_menu_item_parent)];
739
+ } else if ( $_menu_item_menu_item_parent ) {
740
+ $this->menu_item_orphans[intval($item['post_id'])] = (int) $_menu_item_menu_item_parent;
741
+ $_menu_item_menu_item_parent = 0;
742
+ }
743
 
744
+ // wp_update_nav_menu_item expects CSS classes as a space separated string
745
+ $_menu_item_classes = maybe_unserialize( $_menu_item_classes );
746
+ if ( is_array( $_menu_item_classes ) )
747
+ $_menu_item_classes = implode( ' ', $_menu_item_classes );
748
+
749
+ $args = array(
750
+ 'menu-item-object-id' => $_menu_item_object_id,
751
+ 'menu-item-object' => $_menu_item_object,
752
+ 'menu-item-parent-id' => $_menu_item_menu_item_parent,
753
+ 'menu-item-position' => intval( $item['menu_order'] ),
754
+ 'menu-item-type' => $_menu_item_type,
755
+ 'menu-item-title' => $item['post_title'],
756
+ 'menu-item-url' => $_menu_item_url,
757
+ 'menu-item-description' => $item['post_content'],
758
+ 'menu-item-attr-title' => $item['post_excerpt'],
759
+ 'menu-item-target' => $_menu_item_target,
760
+ 'menu-item-classes' => $_menu_item_classes,
761
+ 'menu-item-xfn' => $_menu_item_xfn,
762
+ 'menu-item-status' => $item['status']
763
+ );
764
+
765
+ $id = wp_update_nav_menu_item( $menu_id, 0, $args );
766
+ if ( $id && ! is_wp_error( $id ) )
767
+ $this->processed_menu_items[intval($item['post_id'])] = (int) $id;
768
  }
769
 
770
+ /**
771
+ * If fetching attachments is enabled then attempt to create a new attachment
772
+ *
773
+ * @param array $post Attachment post details from WXR
774
+ * @param string $url URL to fetch attachment from
775
+ * @return int|WP_Error Post ID on success, WP_Error otherwise
776
+ */
777
+ function process_attachment( $post, $url ) {
778
+ if ( ! $this->fetch_attachments )
779
+ return new WP_Error( 'attachment_processing_error',
780
+ __( 'Fetching attachments is not enabled', 'wordpress-importer' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
 
782
+ // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
783
+ if ( preg_match( '|^/[\w\W]+$|', $url ) )
784
+ $url = rtrim( $this->base_url, '/' ) . $url;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
785
 
786
+ $upload = $this->fetch_remote_file( $url, $post );
787
+ if ( is_wp_error( $upload ) )
788
+ return $upload;
 
789
 
790
+ if ( $info = wp_check_filetype( $upload['file'] ) )
791
+ $post['post_mime_type'] = $info['type'];
792
+ else
793
+ return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'wordpress-importer') );
794
 
795
+ $post['guid'] = $upload['url'];
 
 
796
 
797
+ // as per wp-admin/includes/upload.php
798
+ $post_id = wp_insert_attachment( $post, $upload['file'] );
799
+ wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
 
800
 
801
+ // remap resized image URLs, works by stripping the extension and remapping the URL stub.
802
+ if ( preg_match( '!^image/!', $info['type'] ) ) {
803
+ $parts = pathinfo( $url );
804
+ $name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
805
 
806
+ $parts_new = pathinfo( $upload['url'] );
807
+ $name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
808
 
809
+ $this->url_remap[$parts['dirname'] . '/' . $name] = $parts_new['dirname'] . '/' . $name_new;
810
+ }
811
 
812
+ return $post_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  }
814
 
815
+ /**
816
+ * Attempt to download a remote file attachment
817
+ *
818
+ * @param string $url URL of item to fetch
819
+ * @param array $post Attachment details
820
+ * @return array|WP_Error Local file location details on success, WP_Error otherwise
821
+ */
822
+ function fetch_remote_file( $url, $post ) {
823
+ // extract the file name and extension from the url
824
+ $file_name = basename( $url );
825
+
826
+ // get placeholder file in the upload dir with a unique, sanitized filename
827
+ $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
828
+ if ( $upload['error'] )
829
+ return new WP_Error( 'upload_dir_error', $upload['error'] );
830
+
831
+ // fetch the remote url and write it to the placeholder file
832
+ /*EDITED CODE START*/
833
+ // fetch the remote url and write it to the placeholder file
834
+ $response = wp_remote_get( $url, array(
835
+ 'stream' => true,
836
+ 'filename' => $upload['file'],
837
+ ) );
838
+
839
+ // request failed
840
+ if ( is_wp_error( $response ) ) {
841
+ unlink( $upload['file'] );
842
+ return $response;
843
+ }
844
+
845
+ $code = (int) wp_remote_retrieve_response_code( $response );
846
+
847
+ // make sure the fetch was successful
848
+ if ( $code !== 200 ) {
849
+ unlink( $upload['file'] );
850
+ return new WP_Error(
851
+ 'import_file_error',
852
+ sprintf(
853
+ __( 'Remote server returned %1$d %2$s for %3$s', 'wordpress-importer' ),
854
+ $code,
855
+ get_status_header_desc( $code ),
856
+ $url
857
+ )
858
+ );
859
+ }
860
+
861
+ $filesize = filesize( $upload['file'] );
862
+ $headers = wp_remote_retrieve_headers( $response );
863
+ /*EDITED CODE END*/
864
+
865
+ if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) {
866
+ @unlink( $upload['file'] );
867
+ return new WP_Error( 'import_file_error', __('Remote file is incorrect size', 'wordpress-importer') );
868
+ }
869
 
870
+ if ( 0 == $filesize ) {
871
+ @unlink( $upload['file'] );
872
+ return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'wordpress-importer') );
873
+ }
 
874
 
875
+ $max_size = (int) $this->max_attachment_size();
876
+ if ( ! empty( $max_size ) && $filesize > $max_size ) {
877
+ @unlink( $upload['file'] );
878
+ return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'wordpress-importer'), size_format($max_size) ) );
879
+ }
 
880
 
881
+ // keep track of the old and new urls so we can substitute them later
882
+ $this->url_remap[$url] = $upload['url'];
883
+ $this->url_remap[$post['guid']] = $upload['url']; // r13735, really needed?
884
+ // keep track of the destination if the remote url is redirected somewhere else
885
+ if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url )
886
+ $this->url_remap[$headers['x-final-location']] = $upload['url'];
887
 
888
+ return $upload;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
889
  }
890
 
891
+ /**
892
+ * Attempt to associate posts and menu items with previously missing parents
893
+ *
894
+ * An imported post's parent may not have been imported when it was first created
895
+ * so try again. Similarly for child menu items and menu items which were missing
896
+ * the object (e.g. post) they represent in the menu
897
+ */
898
+ function backfill_parents() {
899
+ global $wpdb;
900
+
901
+ // find parents for post orphans
902
+ foreach ( $this->post_orphans as $child_id => $parent_id ) {
903
+ $local_child_id = $local_parent_id = false;
904
+ if ( isset( $this->processed_posts[$child_id] ) )
905
+ $local_child_id = $this->processed_posts[$child_id];
906
+ if ( isset( $this->processed_posts[$parent_id] ) )
907
+ $local_parent_id = $this->processed_posts[$parent_id];
908
+
909
+ if ( $local_child_id && $local_parent_id )
910
+ $wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
911
+ }
912
+
913
+ // all other posts/terms are imported, retry menu items with missing associated object
914
+ $missing_menu_items = $this->missing_menu_items;
915
+ foreach ( $missing_menu_items as $item )
916
+ $this->process_menu_item( $item );
917
+
918
+ // find parents for menu item orphans
919
+ foreach ( $this->menu_item_orphans as $child_id => $parent_id ) {
920
+ $local_child_id = $local_parent_id = 0;
921
+ if ( isset( $this->processed_menu_items[$child_id] ) )
922
+ $local_child_id = $this->processed_menu_items[$child_id];
923
+ if ( isset( $this->processed_menu_items[$parent_id] ) )
924
+ $local_parent_id = $this->processed_menu_items[$parent_id];
925
+
926
+ if ( $local_child_id && $local_parent_id )
927
+ update_post_meta( $local_child_id, '_menu_item_menu_item_parent', (int) $local_parent_id );
928
+ }
929
  }
 
930
 
931
+ /**
932
+ * Use stored mapping information to update old attachment URLs
933
+ */
934
+ function backfill_attachment_urls() {
935
+ global $wpdb;
936
+ // make sure we do the longest urls first, in case one is a substring of another
937
+ uksort( $this->url_remap, array(&$this, 'cmpr_strlen') );
938
+
939
+ foreach ( $this->url_remap as $from_url => $to_url ) {
940
+ // remap urls in post_content
941
+ $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );
942
+ // remap enclosure urls
943
+ $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) );
944
+ }
945
  }
 
946
 
947
+ /**
948
+ * Update _thumbnail_id meta to new, imported attachment IDs
949
+ */
950
+ function remap_featured_images() {
951
+ // cycle through posts that have a featured image
952
+ foreach ( $this->featured_images as $post_id => $value ) {
953
+ if ( isset( $this->processed_posts[$value] ) ) {
954
+ $new_id = $this->processed_posts[$value];
955
+ // only update if there's a difference
956
+ if ( $new_id != $value )
957
+ update_post_meta( $post_id, '_thumbnail_id', $new_id );
958
+ }
959
  }
960
  }
 
961
 
962
+ /**
963
+ * Parse a WXR file
964
+ *
965
+ * @param string $file Path to WXR file for parsing
966
+ * @return array Information gathered from the WXR file
967
+ */
968
+ function parse( $file ) {
969
+ $parser = new Acme_Demo_Setup_WXR_Parser();
970
+ return $parser->parse( $file );
971
+ }
972
 
973
 
974
+ /**
975
+ * Decide if the given meta key maps to information we will want to import
976
+ *
977
+ * @param string $key The meta key to check
978
+ * @return string|bool The key if we do want to import, false if not
979
+ */
980
+ function is_valid_meta_key( $key ) {
981
+ // skip attachment metadata since we'll regenerate it from scratch
982
+ // skip _edit_lock as not relevant for import
983
+ if ( in_array( $key, array( '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock' ) ) )
984
+ return false;
985
+ return $key;
986
+ }
987
 
988
+ /**
989
+ * Decide whether or not the importer is allowed to create users.
990
+ * Default is true, can be filtered via import_allow_create_users
991
+ *
992
+ * @return bool True if creating users is allowed
993
+ */
994
+ function allow_create_users() {
995
+ return apply_filters( 'import_allow_create_users', true );
996
+ }
997
 
998
 
999
+ /**
1000
+ * Decide what the maximum file size for downloaded attachments is.
1001
+ * Default is 0 (unlimited), can be filtered via import_attachment_size_limit
1002
+ *
1003
+ * @return int Maximum attachment file size to import
1004
+ */
1005
+ function max_attachment_size() {
1006
+ return apply_filters( 'import_attachment_size_limit', 0 );
1007
+ }
1008
 
1009
+ /**
1010
+ * Added to http_request_timeout filter to force timeout at 60 seconds during import
1011
+ * @return int 300
1012
+ */
1013
+ function bump_request_timeout( $val ) {
1014
+ return 300;
1015
+ }
1016
 
1017
+ // return the difference in length between two strings
1018
+ function cmpr_strlen( $a, $b ) {
1019
+ return strlen($b) - strlen($a);
1020
+ }
1021
  }
 
1022
 
1023
  } // class_exists( 'Acme_Demo_Setup_Wp_Import' )
readme.txt CHANGED
@@ -3,8 +3,8 @@
3
  Contributors: acmethemes, codersantosh
4
  Tags: demo, dummydata, import, acmethemes, themes, oneclick, customizer, widget
5
  Requires at least: 4.5
6
- Tested up to: 4.7.4
7
- Stable tag: 1.0.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -26,7 +26,7 @@ Setup you site with dummy data easily. Import settings, widgets and content with
26
 
27
  = From WordPress.org =
28
 
29
- 1. Download acme-demo-setup.
30
  2. Upload the 'acme-demo-setup' directory to your '/wp-content/plugins/' directory, using your favorite method (ftp, sftp, scp, etc...)
31
  3. Activate acme-demo-setup from your Appearance > Plugins page.
32
  4. Go to the Appearance -> Acme Demo Setup and upload the ZIP file of dummy data.
@@ -94,6 +94,10 @@ If you have the issues on the plugin [Visit Support Page](https://wordpress.org/
94
 
95
  == Changelog ==
96
 
 
 
 
 
97
  = 1.0.4
98
  * Fixed : undefined function ZipArchive on some hosting
99
 
3
  Contributors: acmethemes, codersantosh
4
  Tags: demo, dummydata, import, acmethemes, themes, oneclick, customizer, widget
5
  Requires at least: 4.5
6
+ Tested up to: 4.8.1
7
+ Stable tag: 1.0.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
26
 
27
  = From WordPress.org =
28
 
29
+ 1. Download acme-demo-setup.zip
30
  2. Upload the 'acme-demo-setup' directory to your '/wp-content/plugins/' directory, using your favorite method (ftp, sftp, scp, etc...)
31
  3. Activate acme-demo-setup from your Appearance > Plugins page.
32
  4. Go to the Appearance -> Acme Demo Setup and upload the ZIP file of dummy data.
94
 
95
  == Changelog ==
96
 
97
+ = 1.0.5
98
+ * Fixed : Text Domain
99
+ * Added : Error
100
+
101
  = 1.0.4
102
  * Fixed : undefined function ZipArchive on some hosting
103