Wordpress 2.3.2
[autoinstalls/wordpress.git] / wp-admin / import / wordpress.php
1 <?php
2
3 class WP_Import {
4
5         var $posts = array ();
6         var $posts_processed = array ();
7     // Array of arrays. [[0] => XML fragment, [1] => New post ID]
8         var $file;
9         var $id;
10         var $mtnames = array ();
11         var $newauthornames = array ();
12         var $j = -1;
13
14         function header() {
15                 echo '<div class="wrap">';
16                 echo '<h2>'.__('Import WordPress').'</h2>';
17         }
18
19         function footer() {
20                 echo '</div>';
21         }
22
23         function unhtmlentities($string) { // From php.net for < 4.3 compat
24                 $trans_tbl = get_html_translation_table(HTML_ENTITIES);
25                 $trans_tbl = array_flip($trans_tbl);
26                 return strtr($string, $trans_tbl);
27         }
28
29         function greet() {
30                 echo '<div class="narrow">';
31                 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>';
32                 echo '<p>'.__('Choose a WordPress WXR file to upload, then click Upload file and import.').'</p>';
33                 wp_import_upload_form("admin.php?import=wordpress&amp;step=1");
34                 echo '</div>';
35         }
36
37         function get_tag( $string, $tag ) {
38                 global $wpdb;
39                 preg_match("|<$tag.*?>(.*?)</$tag>|is", $string, $return);
40                 $return = preg_replace('|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1]);
41                 $return = $wpdb->escape( trim( $return ) );
42                 return $return;
43         }
44
45         function users_form($n) {
46                 global $wpdb, $testing;
47                 $users = $wpdb->get_results("SELECT user_login FROM $wpdb->users ORDER BY user_login");
48 ?><select name="userselect[<?php echo $n; ?>]">
49         <option value="#NONE#">- Select -</option>
50         <?php
51                 foreach ($users as $user) {
52                         echo '<option value="'.$user->user_login.'">'.$user->user_login.'</option>';
53                 }
54 ?>
55         </select>
56         <?php
57         }
58
59         //function to check the authorname and do the mapping
60         function checkauthor($author) {
61                 global $wpdb;
62                 //mtnames is an array with the names in the mt import file
63                 $pass = 'changeme';
64                 if (!(in_array($author, $this->mtnames))) { //a new mt author name is found
65                         ++ $this->j;
66                         $this->mtnames[$this->j] = $author; //add that new mt author name to an array
67                         $user_id = username_exists($this->newauthornames[$this->j]); //check if the new author name defined by the user is a pre-existing wp user
68                         if (!$user_id) { //banging my head against the desk now.
69                                 if ($this->newauthornames[$this->j] == 'left_blank') { //check if the user does not want to change the authorname
70                                         $user_id = wp_create_user($author, $pass);
71                                         $this->newauthornames[$this->j] = $author; //now we have a name, in the place of left_blank.
72                                 } else {
73                                         $user_id = wp_create_user($this->newauthornames[$this->j], $pass);
74                                 }
75                         } else {
76                                 return $user_id; // return pre-existing wp username if it exists
77                         }
78                 } else {
79                         $key = array_search($author, $this->mtnames); //find the array key for $author in the $mtnames array
80                         $user_id = username_exists($this->newauthornames[$key]); //use that key to get the value of the author's name from $newauthornames
81                 }
82
83                 return $user_id;
84         }
85
86         function get_entries() {
87                 set_magic_quotes_runtime(0);
88
89                 $this->posts = array();
90                 $this->categories = array();
91                 $this->tags = array();
92                 $num = 0;
93                 $doing_entry = false;
94
95                 $fp = fopen($this->file, 'r');
96                 if ($fp) {
97                         while ( !feof($fp) ) {
98                                 $importline = rtrim(fgets($fp));
99
100                                 if ( false !== strpos($importline, '<wp:category>') ) {
101                                         preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
102                                         $this->categories[] = $category[1];
103                                         continue;
104                                 }
105                                 if ( false !== strpos($importline, '<wp:tag>') ) {
106                                         preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
107                                         $this->tags[] = $tag[1];
108                                         continue;
109                                 }
110                                 if ( false !== strpos($importline, '<item>') ) {
111                                         $this->posts[$num] = '';
112                                         $doing_entry = true;
113                                         continue;
114                                 }
115                                 if ( false !== strpos($importline, '</item>') ) {
116                                         $num++;
117                                         $doing_entry = false;
118                                         continue;
119                                 }
120                                 if ( $doing_entry ) {
121                                         $this->posts[$num] .= $importline . "\n";
122                                 }
123                         }
124
125                         foreach ($this->posts as $post) {
126                                 $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
127                                 if ($post_ID) {
128                                         $this->posts_processed[$post_ID][0] = &$post;
129                                         $this->posts_processed[$post_ID][1] = 0;
130                                 }
131                         }
132
133                         fclose($fp);
134                 }
135         }
136
137         function get_wp_authors() {
138                 $temp = array ();
139                 $i = -1;
140                 foreach ($this->posts as $post) {
141                         if ('' != trim($post)) {
142                                 ++ $i;
143                                 $author = $this->get_tag( $post, 'dc:creator' );
144                                 array_push($temp, "$author"); //store the extracted author names in a temporary array
145                         }
146                 }
147
148                 // 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.
149                 $authors[0] = array_shift($temp);
150                 $y = count($temp) + 1;
151                 for ($x = 1; $x < $y; $x ++) {
152                         $next = array_shift($temp);
153                         if (!(in_array($next, $authors)))
154                                 array_push($authors, "$next");
155                 }
156
157                 return $authors;
158         }
159
160         function get_authors_from_post() {
161                 $formnames = array ();
162                 $selectnames = array ();
163
164                 foreach ($_POST['user'] as $key => $line) {
165                         $newname = trim(stripslashes($line));
166                         if ($newname == '')
167                                 $newname = 'left_blank'; //passing author names from step 1 to step 2 is accomplished by using POST. left_blank denotes an empty entry in the form.
168                         array_push($formnames, "$newname");
169                 } // $formnames is the array with the form entered names
170
171                 foreach ($_POST['userselect'] as $user => $key) {
172                         $selected = trim(stripslashes($key));
173                         array_push($selectnames, "$selected");
174                 }
175
176                 $count = count($formnames);
177                 for ($i = 0; $i < $count; $i ++) {
178                         if ($selectnames[$i] != '#NONE#') { //if no name was selected from the select menu, use the name entered in the form
179                                 array_push($this->newauthornames, "$selectnames[$i]");
180                         } else {
181                                 array_push($this->newauthornames, "$formnames[$i]");
182                         }
183                 }
184         }
185
186         function wp_authors_form() {
187 ?>
188 <h2><?php _e('Assign Authors'); ?></h2>
189 <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>
190 <p><?php _e('If a new user is created by WordPress, the password will be set, by default, to "changeme". Quite suggestive, eh? ;)'); ?></p>
191         <?php
192
193
194                 $authors = $this->get_wp_authors();
195                 echo '<ol id="authors">';
196                 echo '<form action="?import=wordpress&amp;step=2&amp;id=' . $this->id . '" method="post">';
197                 wp_nonce_field('import-wordpress');
198                 $j = -1;
199                 foreach ($authors as $author) {
200                         ++ $j;
201                         echo '<li>'.__('Current author:').' <strong>'.$author.'</strong><br />'.sprintf(__('Create user %1$s or map to existing'), ' <input type="text" value="'.$author.'" name="'.'user[]'.'" maxlength="30"> <br />');
202                         $this->users_form($j);
203                         echo '</li>';
204                 }
205
206                 echo '<input type="submit" value="Submit">'.'<br />';
207                 echo '</form>';
208                 echo '</ol>';
209
210         }
211
212         function select_authors() {
213                 $file = wp_import_handle_upload();
214                 if ( isset($file['error']) ) {
215                         echo '<p>'.__('Sorry, there has been an error.').'</p>';
216                         echo '<p><strong>' . $file['error'] . '</strong></p>';
217                         return;
218                 }
219                 $this->file = $file['file'];
220                 $this->id = (int) $file['id'];
221
222                 $this->get_entries();
223                 $this->wp_authors_form();
224         }
225
226         function process_categories() {
227                 global $wpdb;
228
229                 $cat_names = (array) get_terms('category', 'fields=names');
230
231                 while ( $c = array_shift($this->categories) ) {
232                         $cat_name = trim($this->get_tag( $c, 'wp:cat_name' ));
233
234                         // If the category exists we leave it alone
235                         if ( in_array($cat_name, $cat_names) )
236                                 continue;
237
238                         $category_nicename      = $this->get_tag( $c, 'wp:category_nicename' );
239                         $posts_private          = (int) $this->get_tag( $c, 'wp:posts_private' );
240                         $links_private          = (int) $this->get_tag( $c, 'wp:links_private' );
241
242                         $parent = $this->get_tag( $c, 'wp:category_parent' );
243
244                         if ( empty($parent) )
245                                 $category_parent = '0';
246                         else
247                                 $category_parent = category_exists($parent);
248
249                         $catarr = compact('category_nicename', 'category_parent', 'posts_private', 'links_private', 'posts_private', 'cat_name');
250
251                         $cat_ID = wp_insert_category($catarr);
252                 }
253         }
254
255         function process_tags() {
256                 global $wpdb;
257
258                 $tag_names = (array) get_terms('post_tag', 'fields=names');
259
260                 while ( $c = array_shift($this->tags) ) {
261                         $tag_name = trim($this->get_tag( $c, 'wp:tag_name' ));
262
263                         // If the category exists we leave it alone
264                         if ( in_array($tag_name, $tag_names) )
265                                 continue;
266
267                         $slug = $this->get_tag( $c, 'wp:tag_slug' );
268                         $description = $this->get_tag( $c, 'wp:tag_description' );
269
270                         $tagarr = compact('slug', 'description');
271
272                         $tag_ID = wp_insert_term($tag_name, 'post_tag', $tagarr);
273                 }
274         }
275
276         function process_posts() {
277                 $i = -1;
278                 echo '<ol>';
279
280                 foreach ($this->posts as $post) {
281                         $result = $this->process_post($post);
282                         if ( is_wp_error( $result ) )
283                                 return $result;
284                 }
285
286                 echo '</ol>';
287
288                 wp_import_cleanup($this->id);
289
290                 echo '<h3>'.sprintf(__('All done.').' <a href="%s">'.__('Have fun!').'</a>', get_option('home')).'</h3>';
291         }
292
293         function process_post($post) {
294                 global $wpdb;
295
296                 $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
297                 if ( $post_ID && !empty($this->posts_processed[$post_ID][1]) ) // Processed already
298                         return 0;
299
300                 // There are only ever one of these
301                 $post_title     = $this->get_tag( $post, 'title' );
302                 $post_date      = $this->get_tag( $post, 'wp:post_date' );
303                 $post_date_gmt  = $this->get_tag( $post, 'wp:post_date_gmt' );
304                 $comment_status = $this->get_tag( $post, 'wp:comment_status' );
305                 $ping_status    = $this->get_tag( $post, 'wp:ping_status' );
306                 $post_status    = $this->get_tag( $post, 'wp:status' );
307                 $post_name      = $this->get_tag( $post, 'wp:post_name' );
308                 $post_parent    = $this->get_tag( $post, 'wp:post_parent' );
309                 $menu_order     = $this->get_tag( $post, 'wp:menu_order' );
310                 $post_type      = $this->get_tag( $post, 'wp:post_type' );
311                 $guid           = $this->get_tag( $post, 'guid' );
312                 $post_author    = $this->get_tag( $post, 'dc:creator' );
313
314                 $post_content = $this->get_tag( $post, 'content:encoded' );
315                 $post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
316                 $post_content = str_replace('<br>', '<br />', $post_content);
317                 $post_content = str_replace('<hr>', '<hr />', $post_content);
318
319                 preg_match_all('|<category domain="tag">(.*?)</category>|is', $post, $tags);
320                 $tags = $tags[1];
321
322                 $tag_index = 0;
323                 foreach ($tags as $tag) {
324                         $tags[$tag_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $tag)));
325                         $tag_index++;
326                 }
327
328                 preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
329                 $categories = $categories[1];
330
331                 $cat_index = 0;
332                 foreach ($categories as $category) {
333                         $categories[$cat_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $category)));
334                         $cat_index++;
335                 }
336
337                 if ($post_id = post_exists($post_title, '', $post_date)) {
338                         echo '<li>';
339                         printf(__('Post <i>%s</i> already exists.'), stripslashes($post_title));
340                 } else {
341
342                         // If it has parent, process parent first.
343                         $post_parent = (int) $post_parent;
344                         if ($parent = $this->posts_processed[$post_parent]) {
345                                 if (!$parent[1]) { 
346                                         $result = $this->process_post($parent[0]); // If not yet, process the parent first.
347                                         if ( is_wp_error( $result ) )
348                                                 return $result;
349                                 }
350                                 $post_parent = $parent[1]; // New ID of the parent;
351                         }
352
353                         echo '<li>';
354                         printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
355
356                         $post_author = $this->checkauthor($post_author); //just so that if a post already exists, new users are not created by checkauthor
357
358                         $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'post_name', 'comment_status', 'ping_status', 'post_modified', 'post_modified_gmt', 'guid', 'post_parent', 'menu_order', 'post_type');
359                         $comment_post_ID = $post_id = wp_insert_post($postdata);
360                         if ( is_wp_error( $post_id ) )
361                                 return $post_id;
362
363                         // Memorize old and new ID.
364                         if ( $post_id && $post_ID && $this->posts_processed[$post_ID] )
365                                 $this->posts_processed[$post_ID][1] = $post_id; // New ID.
366
367                         // Add categories.
368                         if (count($categories) > 0) {
369                                 $post_cats = array();
370                                 foreach ($categories as $category) {
371                                         $slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
372                                         $cat = get_term_by('slug', $slug, 'category');
373                                         $cat_ID = 0;
374                                         if ( ! empty($cat) )
375                                                 $cat_ID = $cat->term_id;
376                                         if ($cat_ID == 0) {
377                                                 $category = $wpdb->escape($category);
378                                                 $cat_ID = wp_insert_category(array('cat_name' => $category));
379                                         }
380                                         $post_cats[] = $cat_ID;
381                                 }
382                                 wp_set_post_categories($post_id, $post_cats);
383                         }
384
385                         // Add tags.
386                         if (count($tags) > 0) {
387                                 $post_tags = array();
388                                 foreach ($tags as $tag) {
389                                         $slug = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
390                                         $tag_obj = get_term_by('slug', $slug, 'post_tag');
391                                         $tag_id = 0;
392                                         if ( ! empty($tag_obj) )
393                                                 $tag_id = $tag_obj->term_id;
394                                         if ( $tag_id == 0 ) {
395                                                 $tag = $wpdb->escape($tag);
396                                                 $tag_id = wp_insert_term($tag, 'post_tag');
397                                                 $tag_id = $tag_id['term_id'];
398                                         }
399                                         $post_tags[] = $tag_id;
400                                 }
401                                 wp_set_post_tags($post_id, $post_tags);
402                         }
403                 }
404
405                 // Now for comments
406                 preg_match_all('|<wp:comment>(.*?)</wp:comment>|is', $post, $comments);
407                 $comments = $comments[1];
408                 $num_comments = 0;
409                 if ( $comments) { foreach ($comments as $comment) {
410                         $comment_author       = $this->get_tag( $comment, 'wp:comment_author');
411                         $comment_author_email = $this->get_tag( $comment, 'wp:comment_author_email');
412                         $comment_author_IP    = $this->get_tag( $comment, 'wp:comment_author_IP');
413                         $comment_author_url   = $this->get_tag( $comment, 'wp:comment_author_url');
414                         $comment_date         = $this->get_tag( $comment, 'wp:comment_date');
415                         $comment_date_gmt     = $this->get_tag( $comment, 'wp:comment_date_gmt');
416                         $comment_content      = $this->get_tag( $comment, 'wp:comment_content');
417                         $comment_approved     = $this->get_tag( $comment, 'wp:comment_approved');
418                         $comment_type         = $this->get_tag( $comment, 'wp:comment_type');
419                         $comment_parent       = $this->get_tag( $comment, 'wp:comment_parent');
420
421                         if ( !comment_exists($comment_author, $comment_date) ) {
422                                 $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');
423                                 wp_insert_comment($commentdata);
424                                 $num_comments++;
425                         }
426                 } }
427
428                 if ( $num_comments )
429                         printf(' '.__('(%s comments)'), $num_comments);
430
431                 // Now for post meta
432                 preg_match_all('|<wp:postmeta>(.*?)</wp:postmeta>|is', $post, $postmeta);
433                 $postmeta = $postmeta[1];
434                 if ( $postmeta) { foreach ($postmeta as $p) {
435                         $key   = $this->get_tag( $p, 'wp:meta_key' );
436                         $value = $this->get_tag( $p, 'wp:meta_value' );
437                         $value = stripslashes($value); // add_post_meta() will escape.
438                         add_post_meta( $post_id, $key, $value );
439                 } }
440         }
441
442         function import() {
443                 $this->id = (int) $_GET['id'];
444
445                 $this->file = get_attached_file($this->id);
446                 $this->get_authors_from_post();
447                 $this->get_entries();
448                 $this->process_categories();
449                 $this->process_tags();
450                 $result = $this->process_posts();
451                 if ( is_wp_error( $result ) )
452                         return $result;
453         }
454
455         function dispatch() {
456                 if (empty ($_GET['step']))
457                         $step = 0;
458                 else
459                         $step = (int) $_GET['step'];
460
461                 $this->header();
462                 switch ($step) {
463                         case 0 :
464                                 $this->greet();
465                                 break;
466                         case 1 :
467                                 check_admin_referer('import-upload');
468                                 $this->select_authors();
469                                 break;
470                         case 2:
471                                 check_admin_referer('import-wordpress');
472                                 $result = $this->import();
473                                 if ( is_wp_error( $result ) )
474                                         echo $result->get_error_message();
475                                 break;
476                 }
477                 $this->footer();
478         }
479
480         function WP_Import() {
481                 // Nothing.
482         }
483 }
484
485 $wp_import = new WP_Import();
486
487 register_importer('wordpress', 'WordPress', __('Import <strong>posts, comments, custom fields, pages, and categories</strong> from a WordPress export file'), array ($wp_import, 'dispatch'));
488
489 ?>