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