]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/import/wordpress.php
Wordpress 2.8.5-scripts
[autoinstalls/wordpress.git] / wp-admin / import / wordpress.php
1 <?php
2 /**
3  * WordPress Importer
4  *
5  * @package WordPress
6  * @subpackage Importer
7  */
8
9 /**
10  * WordPress Importer
11  *
12  * Will process the WordPress eXtended RSS files that you upload from the export
13  * file.
14  *
15  * @since unknown
16  */
17 class WP_Import {
18
19         var $post_ids_processed = array ();
20         var $orphans = array ();
21         var $file;
22         var $id;
23         var $mtnames = array ();
24         var $newauthornames = array ();
25         var $allauthornames = array ();
26
27         var $author_ids = array ();
28         var $tags = array ();
29         var $categories = array ();
30
31         var $j = -1;
32         var $fetch_attachments = false;
33         var $url_remap = array ();
34
35         function header() {
36                 echo '<div class="wrap">';
37                 screen_icon();
38                 echo '<h2>'.__('Import WordPress').'</h2>';
39         }
40
41         function footer() {
42                 echo '</div>';
43         }
44
45         function unhtmlentities($string) { // From php.net for < 4.3 compat
46                 $trans_tbl = get_html_translation_table(HTML_ENTITIES);
47                 $trans_tbl = array_flip($trans_tbl);
48                 return strtr($string, $trans_tbl);
49         }
50
51         function greet() {
52                 echo '<div class="narrow">';
53                 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 blog.').'</p>';
54                 echo '<p>'.__('Choose a WordPress WXR file to upload, then click Upload file and import.').'</p>';
55                 wp_import_upload_form("admin.php?import=wordpress&amp;step=1");
56                 echo '</div>';
57         }
58
59         function get_tag( $string, $tag ) {
60                 global $wpdb;
61                 preg_match("|<$tag.*?>(.*?)</$tag>|is", $string, $return);
62                 $return = preg_replace('|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1]);
63                 $return = $wpdb->escape( trim( $return ) );
64                 return $return;
65         }
66
67         function has_gzip() {
68                 return is_callable('gzopen');
69         }
70
71         function fopen($filename, $mode='r') {
72                 if ( $this->has_gzip() )
73                         return gzopen($filename, $mode);
74                 return fopen($filename, $mode);
75         }
76
77         function feof($fp) {
78                 if ( $this->has_gzip() )
79                         return gzeof($fp);
80                 return feof($fp);
81         }
82
83         function fgets($fp, $len=8192) {
84                 if ( $this->has_gzip() )
85                         return gzgets($fp, $len);
86                 return fgets($fp, $len);
87         }
88
89         function fclose($fp) {
90                 if ( $this->has_gzip() )
91                         return gzclose($fp);
92                 return fclose($fp);
93         }
94
95         function get_entries($process_post_func=NULL) {
96                 set_magic_quotes_runtime(0);
97
98                 $doing_entry = false;
99                 $is_wxr_file = false;
100
101                 $fp = $this->fopen($this->file, 'r');
102                 if ($fp) {
103                         while ( !$this->feof($fp) ) {
104                                 $importline = rtrim($this->fgets($fp));
105
106                                 // this doesn't check that the file is perfectly valid but will at least confirm that it's not the wrong format altogether
107                                 if ( !$is_wxr_file && preg_match('|xmlns:wp="http://wordpress[.]org/export/\d+[.]\d+/"|', $importline) )
108                                         $is_wxr_file = true;
109
110                                 if ( false !== strpos($importline, '<wp:base_site_url>') ) {
111                                         preg_match('|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url);
112                                         $this->base_url = $url[1];
113                                         continue;
114                                 }
115                                 if ( false !== strpos($importline, '<wp:category>') ) {
116                                         preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
117                                         $this->categories[] = $category[1];
118                                         continue;
119                                 }
120                                 if ( false !== strpos($importline, '<wp:tag>') ) {
121                                         preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
122                                         $this->tags[] = $tag[1];
123                                         continue;
124                                 }
125                                 if ( false !== strpos($importline, '<item>') ) {
126                                         $this->post = '';
127                                         $doing_entry = true;
128                                         continue;
129                                 }
130                                 if ( false !== strpos($importline, '</item>') ) {
131                                         $doing_entry = false;
132                                         if ($process_post_func)
133                                                 call_user_func($process_post_func, $this->post);
134                                         continue;
135                                 }
136                                 if ( $doing_entry ) {
137                                         $this->post .= $importline . "\n";
138                                 }
139                         }
140
141                         $this->fclose($fp);
142                 }
143
144                 return $is_wxr_file;
145
146         }
147
148         function get_wp_authors() {
149                 // We need to find unique values of author names, while preserving the order, so this function emulates the unique_value(); php function, without the sorting.
150                 $temp = $this->allauthornames;
151                 $authors[0] = array_shift($temp);
152                 $y = count($temp) + 1;
153                 for ($x = 1; $x < $y; $x ++) {
154                         $next = array_shift($temp);
155                         if (!(in_array($next, $authors)))
156                                 array_push($authors, "$next");
157                 }
158
159                 return $authors;
160         }
161
162         function get_authors_from_post() {
163                 global $current_user;
164
165                 // this will populate $this->author_ids with a list of author_names => user_ids
166
167                 foreach ( $_POST['author_in'] as $i => $in_author_name ) {
168
169                         if ( !empty($_POST['user_select'][$i]) ) {
170                                 // an existing user was selected in the dropdown list
171                                 $user = get_userdata( intval($_POST['user_select'][$i]) );
172                                 if ( isset($user->ID) )
173                                         $this->author_ids[$in_author_name] = $user->ID;
174                         }
175                         elseif ( $this->allow_create_users() ) {
176                                 // nothing was selected in the dropdown list, so we'll use the name in the text field
177
178                                 $new_author_name = trim($_POST['user_create'][$i]);
179                                 // if the user didn't enter a name, assume they want to use the same name as in the import file
180                                 if ( empty($new_author_name) )
181                                         $new_author_name = $in_author_name;
182
183                                 $user_id = username_exists($new_author_name);
184                                 if ( !$user_id ) {
185                                         $user_id = wp_create_user($new_author_name, wp_generate_password());
186                                 }
187
188                                 $this->author_ids[$in_author_name] = $user_id;
189                         }
190
191                         // failsafe: if the user_id was invalid, default to the current user
192                         if ( empty($this->author_ids[$in_author_name]) ) {
193                                 $this->author_ids[$in_author_name] = intval($current_user->ID);
194                         }
195                 }
196
197         }
198
199         function wp_authors_form() {
200 ?>
201 <?php screen_icon(); ?>
202 <h2><?php _e('Assign Authors'); ?></h2>
203 <p><?php _e('To make it easier for you to edit and save the imported posts and drafts, you may want to change the name of the author of the posts. For example, you may want to import all the entries as <code>admin</code>s entries.'); ?></p>
204 <?php
205         if ( $this->allow_create_users() ) {
206                 echo '<p>'.__('If a new user is created by WordPress, a password will be randomly generated. Manually change the user&#8217;s details if necessary.')."</p>\n";
207         }
208
209
210                 $authors = $this->get_wp_authors();
211                 echo '<form action="?import=wordpress&amp;step=2&amp;id=' . $this->id . '" method="post">';
212                 wp_nonce_field('import-wordpress');
213                 echo '<ol id="authors">';
214                 $j = -1;
215                 foreach ($authors as $author) {
216                         ++ $j;
217                         echo '<li>'.__('Import author:').' <strong>'.$author.'</strong><br />';
218                         $this->users_form($j, $author);
219                         echo '</li>';
220                 }
221
222                 if ( $this->allow_fetch_attachments() ) {
223 ?>
224 </ol>
225 <?php screen_icon(); ?>
226 <h2><?php _e('Import Attachments'); ?></h2>
227 <p>
228         <input type="checkbox" value="1" name="attachments" id="import-attachments" />
229         <label for="import-attachments"><?php _e('Download and import file attachments') ?></label>
230 </p>
231
232 <?php
233                 }
234
235                 echo '<p class="submit">';
236                 echo '<input type="submit" class="button" value="'. esc_attr__('Submit') .'" />'.'<br />';
237                 echo '</p>';
238                 echo '</form>';
239
240         }
241
242         function users_form($n, $author) {
243
244                 if ( $this->allow_create_users() ) {
245                         printf('<label>'.__('Create user %1$s or map to existing'), ' <input type="text" value="'. esc_attr($author) .'" name="'.'user_create['.intval($n).']'.'" maxlength="30" /></label> <br />');
246                 }
247                 else {
248                         echo __('Map to existing').'<br />';
249                 }
250
251                 // keep track of $n => $author name
252                 echo '<input type="hidden" name="author_in['.intval($n).']" value="' . esc_attr($author).'" />';
253
254                 $users = get_users_of_blog();
255 ?><select name="user_select[<?php echo $n; ?>]">
256         <option value="0"><?php _e('- Select -'); ?></option>
257         <?php
258                 foreach ($users as $user) {
259                         echo '<option value="'.$user->user_id.'">'.$user->user_login.'</option>';
260                 }
261 ?>
262         </select>
263         <?php
264         }
265
266         function select_authors() {
267                 $is_wxr_file = $this->get_entries(array(&$this, 'process_author'));
268                 if ( $is_wxr_file ) {
269                         $this->wp_authors_form();
270                 }
271                 else {
272                         echo '<h2>'.__('Invalid file').'</h2>';
273                         echo '<p>'.__('Please upload a valid WXR (WordPress eXtended RSS) export file.').'</p>';
274                 }
275         }
276
277         // fetch the user ID for a given author name, respecting the mapping preferences
278         function checkauthor($author) {
279                 global $current_user;
280
281                 if ( !empty($this->author_ids[$author]) )
282                         return $this->author_ids[$author];
283
284                 // failsafe: map to the current user
285                 return $current_user->ID;
286         }
287
288
289
290         function process_categories() {
291                 global $wpdb;
292
293                 $cat_names = (array) get_terms('category', 'fields=names');
294
295                 while ( $c = array_shift($this->categories) ) {
296                         $cat_name = trim($this->get_tag( $c, 'wp:cat_name' ));
297
298                         // If the category exists we leave it alone
299                         if ( in_array($cat_name, $cat_names) )
300                                 continue;
301
302                         $category_nicename      = $this->get_tag( $c, 'wp:category_nicename' );
303                         $category_description = $this->get_tag( $c, 'wp:category_description' );
304                         $posts_private          = (int) $this->get_tag( $c, 'wp:posts_private' );
305                         $links_private          = (int) $this->get_tag( $c, 'wp:links_private' );
306
307                         $parent = $this->get_tag( $c, 'wp:category_parent' );
308
309                         if ( empty($parent) )
310                                 $category_parent = '0';
311                         else
312                                 $category_parent = category_exists($parent);
313
314                         $catarr = compact('category_nicename', 'category_parent', 'posts_private', 'links_private', 'posts_private', 'cat_name', 'category_description');
315
316                         $cat_ID = wp_insert_category($catarr);
317                 }
318         }
319
320         function process_tags() {
321                 global $wpdb;
322
323                 $tag_names = (array) get_terms('post_tag', 'fields=names');
324
325                 while ( $c = array_shift($this->tags) ) {
326                         $tag_name = trim($this->get_tag( $c, 'wp:tag_name' ));
327
328                         // If the category exists we leave it alone
329                         if ( in_array($tag_name, $tag_names) )
330                                 continue;
331
332                         $slug = $this->get_tag( $c, 'wp:tag_slug' );
333                         $description = $this->get_tag( $c, 'wp:tag_description' );
334
335                         $tagarr = compact('slug', 'description');
336
337                         $tag_ID = wp_insert_term($tag_name, 'post_tag', $tagarr);
338                 }
339         }
340
341         function process_author($post) {
342                 $author = $this->get_tag( $post, 'dc:creator' );
343                 if ($author)
344                         $this->allauthornames[] = $author;
345         }
346
347         function process_posts() {
348                 echo '<ol>';
349
350                 $this->get_entries(array(&$this, 'process_post'));
351
352                 echo '</ol>';
353
354                 wp_import_cleanup($this->id);
355                 do_action('import_done', 'wordpress');
356
357                 echo '<h3>'.sprintf(__('All done.').' <a href="%s">'.__('Have fun!').'</a>', get_option('home')).'</h3>';
358         }
359
360         function process_post($post) {
361                 global $wpdb;
362
363                 $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
364                 if ( $post_ID && !empty($this->post_ids_processed[$post_ID]) ) // Processed already
365                         return 0;
366
367                 set_time_limit( 60 );
368
369                 // There are only ever one of these
370                 $post_title     = $this->get_tag( $post, 'title' );
371                 $post_date      = $this->get_tag( $post, 'wp:post_date' );
372                 $post_date_gmt  = $this->get_tag( $post, 'wp:post_date_gmt' );
373                 $comment_status = $this->get_tag( $post, 'wp:comment_status' );
374                 $ping_status    = $this->get_tag( $post, 'wp:ping_status' );
375                 $post_status    = $this->get_tag( $post, 'wp:status' );
376                 $post_name      = $this->get_tag( $post, 'wp:post_name' );
377                 $post_parent    = $this->get_tag( $post, 'wp:post_parent' );
378                 $menu_order     = $this->get_tag( $post, 'wp:menu_order' );
379                 $post_type      = $this->get_tag( $post, 'wp:post_type' );
380                 $post_password  = $this->get_tag( $post, 'wp:post_password' );
381                 $guid           = $this->get_tag( $post, 'guid' );
382                 $post_author    = $this->get_tag( $post, 'dc:creator' );
383
384                 $post_excerpt = $this->get_tag( $post, 'excerpt:encoded' );
385                 $post_excerpt = preg_replace_callback('|<(/?[A-Z]+)|', create_function('$match', 'return "<" . strtolower($match[1]);'), $post_excerpt);
386                 $post_excerpt = str_replace('<br>', '<br />', $post_excerpt);
387                 $post_excerpt = str_replace('<hr>', '<hr />', $post_excerpt);
388
389                 $post_content = $this->get_tag( $post, 'content:encoded' );
390                 $post_content = preg_replace_callback('|<(/?[A-Z]+)|', create_function('$match', 'return "<" . strtolower($match[1]);'), $post_content);
391                 $post_content = str_replace('<br>', '<br />', $post_content);
392                 $post_content = str_replace('<hr>', '<hr />', $post_content);
393
394                 preg_match_all('|<category domain="tag">(.*?)</category>|is', $post, $tags);
395                 $tags = $tags[1];
396
397                 $tag_index = 0;
398                 foreach ($tags as $tag) {
399                         $tags[$tag_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $tag)));
400                         $tag_index++;
401                 }
402
403                 preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
404                 $categories = $categories[1];
405
406                 $cat_index = 0;
407                 foreach ($categories as $category) {
408                         $categories[$cat_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $category)));
409                         $cat_index++;
410                 }
411
412                 $post_exists = post_exists($post_title, '', $post_date);
413
414                 if ( $post_exists ) {
415                         echo '<li>';
416                         printf(__('Post <em>%s</em> already exists.'), stripslashes($post_title));
417                         $comment_post_ID = $post_id = $post_exists;
418                 } else {
419
420                         // If it has parent, process parent first.
421                         $post_parent = (int) $post_parent;
422                         if ($post_parent) {
423                                 // if we already know the parent, map it to the local ID
424                                 if ( $parent = $this->post_ids_processed[$post_parent] ) {
425                                         $post_parent = $parent;  // new ID of the parent
426                                 }
427                                 else {
428                                         // record the parent for later
429                                         $this->orphans[intval($post_ID)] = $post_parent;
430                                 }
431                         }
432
433                         echo '<li>';
434
435                         $post_author = $this->checkauthor($post_author); //just so that if a post already exists, new users are not created by checkauthor
436
437                         $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt', 'post_title', 'post_status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent', 'menu_order', 'post_type', 'post_password');
438                         $postdata['import_id'] = $post_ID;
439                         if ($post_type == 'attachment') {
440                                 $remote_url = $this->get_tag( $post, 'wp:attachment_url' );
441                                 if ( !$remote_url )
442                                         $remote_url = $guid;
443
444                                 $comment_post_ID = $post_id = $this->process_attachment($postdata, $remote_url);
445                                 if ( !$post_id or is_wp_error($post_id) )
446                                         return $post_id;
447                         }
448                         else {
449                                 printf(__('Importing post <em>%s</em>...'), stripslashes($post_title));
450                                 $comment_post_ID = $post_id = wp_insert_post($postdata);
451                         }
452
453                         if ( is_wp_error( $post_id ) )
454                                 return $post_id;
455
456                         // Memorize old and new ID.
457                         if ( $post_id && $post_ID ) {
458                                 $this->post_ids_processed[intval($post_ID)] = intval($post_id);
459                         }
460
461                         // Add categories.
462                         if (count($categories) > 0) {
463                                 $post_cats = array();
464                                 foreach ($categories as $category) {
465                                         if ( '' == $category )
466                                                 continue;
467                                         $slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
468                                         $cat = get_term_by('slug', $slug, 'category');
469                                         $cat_ID = 0;
470                                         if ( ! empty($cat) )
471                                                 $cat_ID = $cat->term_id;
472                                         if ($cat_ID == 0) {
473                                                 $category = $wpdb->escape($category);
474                                                 $cat_ID = wp_insert_category(array('cat_name' => $category));
475                                                 if ( is_wp_error($cat_ID) )
476                                                         continue;
477                                         }
478                                         $post_cats[] = $cat_ID;
479                                 }
480                                 wp_set_post_categories($post_id, $post_cats);
481                         }
482
483                         // Add tags.
484                         if (count($tags) > 0) {
485                                 $post_tags = array();
486                                 foreach ($tags as $tag) {
487                                         if ( '' == $tag )
488                                                 continue;
489                                         $slug = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
490                                         $tag_obj = get_term_by('slug', $slug, 'post_tag');
491                                         $tag_id = 0;
492                                         if ( ! empty($tag_obj) )
493                                                 $tag_id = $tag_obj->term_id;
494                                         if ( $tag_id == 0 ) {
495                                                 $tag = $wpdb->escape($tag);
496                                                 $tag_id = wp_insert_term($tag, 'post_tag');
497                                                 if ( is_wp_error($tag_id) )
498                                                         continue;
499                                                 $tag_id = $tag_id['term_id'];
500                                         }
501                                         $post_tags[] = intval($tag_id);
502                                 }
503                                 wp_set_post_tags($post_id, $post_tags);
504                         }
505                 }
506
507                 // Now for comments
508                 preg_match_all('|<wp:comment>(.*?)</wp:comment>|is', $post, $comments);
509                 $comments = $comments[1];
510                 $num_comments = 0;
511                 if ( $comments) { foreach ($comments as $comment) {
512                         $comment_author       = $this->get_tag( $comment, 'wp:comment_author');
513                         $comment_author_email = $this->get_tag( $comment, 'wp:comment_author_email');
514                         $comment_author_IP    = $this->get_tag( $comment, 'wp:comment_author_IP');
515                         $comment_author_url   = $this->get_tag( $comment, 'wp:comment_author_url');
516                         $comment_date         = $this->get_tag( $comment, 'wp:comment_date');
517                         $comment_date_gmt     = $this->get_tag( $comment, 'wp:comment_date_gmt');
518                         $comment_content      = $this->get_tag( $comment, 'wp:comment_content');
519                         $comment_approved     = $this->get_tag( $comment, 'wp:comment_approved');
520                         $comment_type         = $this->get_tag( $comment, 'wp:comment_type');
521                         $comment_parent       = $this->get_tag( $comment, 'wp:comment_parent');
522
523                         // if this is a new post we can skip the comment_exists() check
524                         if ( !$post_exists || !comment_exists($comment_author, $comment_date) ) {
525                                 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_approved', 'comment_type', 'comment_parent');
526                                 wp_insert_comment($commentdata);
527                                 $num_comments++;
528                         }
529                 } }
530
531                 if ( $num_comments )
532                         printf(' '._n('(%s comment)', '(%s comments)', $num_comments), $num_comments);
533
534                 // Now for post meta
535                 preg_match_all('|<wp:postmeta>(.*?)</wp:postmeta>|is', $post, $postmeta);
536                 $postmeta = $postmeta[1];
537                 if ( $postmeta) { foreach ($postmeta as $p) {
538                         $key   = $this->get_tag( $p, 'wp:meta_key' );
539                         $value = $this->get_tag( $p, 'wp:meta_value' );
540                         $value = stripslashes($value); // add_post_meta() will escape.
541
542                         $this->process_post_meta($post_id, $key, $value);
543
544                 } }
545
546                 do_action('import_post_added', $post_id);
547                 print "</li>\n";
548         }
549
550         function process_post_meta($post_id, $key, $value) {
551                 // the filter can return false to skip a particular metadata key
552                 $_key = apply_filters('import_post_meta_key', $key);
553                 if ( $_key ) {
554                         add_post_meta( $post_id, $_key, $value );
555                         do_action('import_post_meta', $post_id, $_key, $value);
556                 }
557         }
558
559         function process_attachment($postdata, $remote_url) {
560                 if ($this->fetch_attachments and $remote_url) {
561                         printf( __('Importing attachment <em>%s</em>... '), htmlspecialchars($remote_url) );
562
563                         // If the URL is absolute, but does not contain http, upload it assuming the base_site_url variable
564                         if ( preg_match('/^\/[\w\W]+$/', $remote_url) )
565                                 $remote_url = rtrim($this->base_url,'/').$remote_url;
566
567                         $upload = $this->fetch_remote_file($postdata, $remote_url);
568                         if ( is_wp_error($upload) ) {
569                                 printf( __('Remote file error: %s'), htmlspecialchars($upload->get_error_message()) );
570                                 return $upload;
571                         }
572                         else {
573                                 print '('.size_format(filesize($upload['file'])).')';
574                         }
575
576                         if ( $info = wp_check_filetype($upload['file']) ) {
577                                 $postdata['post_mime_type'] = $info['type'];
578                         }
579                         else {
580                                 print __('Invalid file type');
581                                 return;
582                         }
583
584                         $postdata['guid'] = $upload['url'];
585
586                         // as per wp-admin/includes/upload.php
587                         $post_id = wp_insert_attachment($postdata, $upload['file']);
588                         wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
589
590                         // remap the thumbnail url.  this isn't perfect because we're just guessing the original url.
591                         if ( preg_match('@^image/@', $info['type']) && $thumb_url = wp_get_attachment_thumb_url($post_id) ) {
592                                 $parts = pathinfo($remote_url);
593                                 $ext = $parts['extension'];
594                                 $name = basename($parts['basename'], ".{$ext}");
595                                 $this->url_remap[$parts['dirname'] . '/' . $name . '.thumbnail.' . $ext] = $thumb_url;
596                         }
597
598                         return $post_id;
599                 }
600                 else {
601                         printf( __('Skipping attachment <em>%s</em>'), htmlspecialchars($remote_url) );
602                 }
603         }
604
605         function fetch_remote_file($post, $url) {
606                 $upload = wp_upload_dir($post['post_date']);
607
608                 // extract the file name and extension from the url
609                 $file_name = basename($url);
610
611                 // get placeholder file in the upload dir with a unique sanitized filename
612                 $upload = wp_upload_bits( $file_name, 0, '', $post['post_date']);
613                 if ( $upload['error'] ) {
614                         echo $upload['error'];
615                         return new WP_Error( 'upload_dir_error', $upload['error'] );
616                 }
617
618                 // fetch the remote url and write it to the placeholder file
619                 $headers = wp_get_http($url, $upload['file']);
620
621                 //Request failed
622                 if ( ! $headers ) {
623                         @unlink($upload['file']);
624                         return new WP_Error( 'import_file_error', __('Remote server did not respond') );
625                 }
626
627                 // make sure the fetch was successful
628                 if ( $headers['response'] != '200' ) {
629                         @unlink($upload['file']);
630                         return new WP_Error( 'import_file_error', sprintf(__('Remote file returned error response %1$d %2$s'), $headers['response'], get_status_header_desc($headers['response']) ) );
631                 }
632                 elseif ( isset($headers['content-length']) && filesize($upload['file']) != $headers['content-length'] ) {
633                         @unlink($upload['file']);
634                         return new WP_Error( 'import_file_error', __('Remote file is incorrect size') );
635                 }
636
637                 $max_size = $this->max_attachment_size();
638                 if ( !empty($max_size) and filesize($upload['file']) > $max_size ) {
639                         @unlink($upload['file']);
640                         return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', size_format($max_size))) );
641                 }
642
643                 // keep track of the old and new urls so we can substitute them later
644                 $this->url_remap[$url] = $upload['url'];
645                 // if the remote url is redirected somewhere else, keep track of the destination too
646                 if ( $headers['x-final-location'] != $url )
647                         $this->url_remap[$headers['x-final-location']] = $upload['url'];
648
649                 return $upload;
650
651         }
652
653         // sort by strlen, longest string first
654         function cmpr_strlen($a, $b) {
655                 return strlen($b) - strlen($a);
656         }
657
658         // update url references in post bodies to point to the new local files
659         function backfill_attachment_urls() {
660
661                 // make sure we do the longest urls first, in case one is a substring of another
662                 uksort($this->url_remap, array(&$this, 'cmpr_strlen'));
663
664                 global $wpdb;
665                 foreach ($this->url_remap as $from_url => $to_url) {
666                         // remap urls in post_content
667                         $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, '%s', '%s')", $from_url, $to_url) );
668                         // remap enclosure urls
669                         $result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, '%s', '%s') WHERE meta_key='enclosure'", $from_url, $to_url) );
670                 }
671         }
672
673         // update the post_parent of orphans now that we know the local id's of all parents
674         function backfill_parents() {
675                 global $wpdb;
676
677                 foreach ($this->orphans as $child_id => $parent_id) {
678                         $local_child_id = $this->post_ids_processed[$child_id];
679                         $local_parent_id = $this->post_ids_processed[$parent_id];
680                         if ($local_child_id and $local_parent_id) {
681                                 $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = %d WHERE ID = %d", $local_parent_id, $local_child_id));
682                         }
683                 }
684         }
685
686         function is_valid_meta_key($key) {
687                 // skip attachment metadata since we'll regenerate it from scratch
688                 if ( $key == '_wp_attached_file' || $key == '_wp_attachment_metadata' )
689                         return false;
690                 return $key;
691         }
692
693         // give the user the option of creating new users to represent authors in the import file?
694         function allow_create_users() {
695                 return apply_filters('import_allow_create_users', true);
696         }
697
698         // give the user the option of downloading and importing attached files
699         function allow_fetch_attachments() {
700                 return apply_filters('import_allow_fetch_attachments', true);
701         }
702
703         function max_attachment_size() {
704                 // can be overridden with a filter - 0 means no limit
705                 return apply_filters('import_attachment_size_limit', 0);
706         }
707
708         function import_start() {
709                 wp_defer_term_counting(true);
710                 wp_defer_comment_counting(true);
711                 do_action('import_start');
712         }
713
714         function import_end() {
715                 do_action('import_end');
716
717                 // clear the caches after backfilling
718                 foreach ($this->post_ids_processed as $post_id)
719                         clean_post_cache($post_id);
720
721                 wp_defer_term_counting(false);
722                 wp_defer_comment_counting(false);
723         }
724
725         function import($id, $fetch_attachments = false) {
726                 $this->id = (int) $id;
727                 $this->fetch_attachments = ($this->allow_fetch_attachments() && (bool) $fetch_attachments);
728
729                 add_filter('import_post_meta_key', array($this, 'is_valid_meta_key'));
730                 $file = get_attached_file($this->id);
731                 $this->import_file($file);
732         }
733
734         function import_file($file) {
735                 $this->file = $file;
736
737                 $this->import_start();
738                 $this->get_authors_from_post();
739                 wp_suspend_cache_invalidation(true);
740                 $this->get_entries();
741                 $this->process_categories();
742                 $this->process_tags();
743                 $result = $this->process_posts();
744                 wp_suspend_cache_invalidation(false);
745                 $this->backfill_parents();
746                 $this->backfill_attachment_urls();
747                 $this->import_end();
748
749                 if ( is_wp_error( $result ) )
750                         return $result;
751         }
752
753         function handle_upload() {
754                 $file = wp_import_handle_upload();
755                 if ( isset($file['error']) ) {
756                         echo '<p>'.__('Sorry, there has been an error.').'</p>';
757                         echo '<p><strong>' . $file['error'] . '</strong></p>';
758                         return false;
759                 }
760                 $this->file = $file['file'];
761                 $this->id = (int) $file['id'];
762                 return true;
763         }
764
765         function dispatch() {
766                 if (empty ($_GET['step']))
767                         $step = 0;
768                 else
769                         $step = (int) $_GET['step'];
770
771                 $this->header();
772                 switch ($step) {
773                         case 0 :
774                                 $this->greet();
775                                 break;
776                         case 1 :
777                                 check_admin_referer('import-upload');
778                                 if ( $this->handle_upload() )
779                                         $this->select_authors();
780                                 break;
781                         case 2:
782                                 check_admin_referer('import-wordpress');
783                                 $result = $this->import( $_GET['id'], $_POST['attachments'] );
784                                 if ( is_wp_error( $result ) )
785                                         echo $result->get_error_message();
786                                 break;
787                 }
788                 $this->footer();
789         }
790
791         function WP_Import() {
792                 // Nothing.
793         }
794 }
795
796 /**
797  * Register WordPress Importer
798  *
799  * @since unknown
800  * @var WP_Import
801  * @name $wp_import
802  */
803 $wp_import = new WP_Import();
804
805 register_importer('wordpress', 'WordPress', __('Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.'), array ($wp_import, 'dispatch'));
806
807 ?>