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