root/tags/1.3/wp-admin/import/wordpress.php

Revision 1103, 14.5 kB (checked in by donncha, 1 year ago)

Assign authors correctly, props washort, fixes #435

Line 
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 = get_users_of_blog($wpdb->blogid);
48 ?><select name="userselect[<?php echo attribute_escape($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
63         $map = $_POST['userselect'];
64
65         $user_id = username_exists($map[$author]); //use that key to get the value of the author's name from $newauthornames
66
67         return $user_id;
68     }
69
70     function get_entries() {
71         set_magic_quotes_runtime(0);
72
73         $this->posts = array();
74         $this->categories = array();
75         $this->tags = array();
76         $num = 0;
77         $doing_entry = false;
78
79         $fp = fopen($this->file, 'r');
80         if ($fp) {
81             while ( !feof($fp) ) {
82                 $importline = rtrim(fgets($fp));
83
84                 if ( false !== strpos($importline, '<wp:category>') ) {
85                     preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
86                     $this->categories[] = $category[1];
87                     continue;
88                 }
89                 if ( false !== strpos($importline, '<wp:tag>') ) {
90                     preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
91                     $this->tags[] = $tag[1];
92                     continue;
93                 }
94                 if ( false !== strpos($importline, '<item>') ) {
95                     $this->posts[$num] = '';
96                     $doing_entry = true;
97                     continue;
98                 }
99                 if ( false !== strpos($importline, '</item>') ) {
100                     $num++;
101                     $doing_entry = false;
102                     continue;
103                 }
104                 if ( $doing_entry ) {
105                     $this->posts[$num] .= $importline . "\n";
106                 }
107             }
108
109             foreach ($this->posts as $post) {
110                 $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
111                 if ($post_ID) {
112                     $this->posts_processed[$post_ID][0] = &$post;
113                     $this->posts_processed[$post_ID][1] = 0;
114                 }
115             }
116
117             fclose($fp);
118         }
119     }
120
121     function get_wp_authors() {
122         $temp = array ();
123         $i = -1;
124         foreach ($this->posts as $post) {
125             if ('' != trim($post)) {
126                 ++ $i;
127                 $author = $this->get_tag( $post, 'dc:creator' );
128                 array_push($temp, "$author"); //store the extracted author names in a temporary array
129             }
130         }
131
132         // 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.
133         $authors[0] = array_shift($temp);
134         $y = count($temp) + 1;
135         for ($x = 1; $x < $y; $x ++) {
136             $next = array_shift($temp);
137             if (!(in_array($next, $authors)))
138                 array_push($authors, "$next");
139         }
140
141         return $authors;
142     }
143
144     function get_authors_from_post() {
145         $formnames = array ();
146         $selectnames = array ();
147
148         foreach ((array)$_POST['user'] as $key => $line) {
149             $newname = trim(stripslashes($line));
150             if ($newname == '')
151                 $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.
152             array_push($formnames, "$newname");
153         } // $formnames is the array with the form entered names
154
155         foreach ($_POST['userselect'] as $user => $key) {
156             $selected = trim(stripslashes($key));
157             array_push($selectnames, "$selected");
158         }
159
160         $count = count($formnames);
161         for ($i = 0; $i < $count; $i ++) {
162             if ($selectnames[$i] != '#NONE#') { //if no name was selected from the select menu, use the name entered in the form
163                 array_push($this->newauthornames, "$selectnames[$i]");
164             } else {
165                 array_push($this->newauthornames, "$formnames[$i]");
166             }
167         }
168     }
169
170     function wp_authors_form() {
171 ?>
172 <h2><?php _e('Assign Authors'); ?></h2>
173 <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>
174     <?php
175
176
177         $authors = $this->get_wp_authors();
178         echo '<ol id="authors">';
179         echo '<form action="?import=wordpress&amp;step=2&amp;id=' . $this->id . '" method="post">';
180         wp_nonce_field('import-wordpress');
181         $j = -1;
182         foreach ($authors as $author) {
183             ++ $j;
184             echo '<li>'.__('Current author:').' <strong>'.$author.'</strong><br />'.'Map to existing: ';
185             $this->users_form($author);
186             echo '</li>';
187         }
188
189         echo '<input type="submit" value="Submit">'.'<br />';
190         echo '</form>';
191         echo '</ol>';
192
193     }
194
195     function select_authors() {
196         $file = wp_import_handle_upload();
197         if ( isset($file['error']) ) {
198             echo '<p>'.__('Sorry, there has been an error.').'</p>';
199             echo '<p><strong>' . $file['error'] . '</strong></p>';
200             return;
201         }
202         $this->file = $file['file'];
203         $this->id = (int) $file['id'];
204
205         $this->get_entries();
206         $this->wp_authors_form();
207     }
208
209     function process_categories() {
210         global $wpdb;
211
212         $cat_names = (array) get_terms('category', 'fields=names');
213
214         while ( $c = array_shift($this->categories) ) {
215             $cat_name = trim($this->get_tag( $c, 'wp:cat_name' ));
216
217             // If the category exists we leave it alone
218             if ( in_array($cat_name, $cat_names) )
219                 continue;
220
221             $category_nicename    = $this->get_tag( $c, 'wp:category_nicename' );
222             $posts_private        = (int) $this->get_tag( $c, 'wp:posts_private' );
223             $links_private        = (int) $this->get_tag( $c, 'wp:links_private' );
224
225             $parent = $this->get_tag( $c, 'wp:category_parent' );
226
227             if ( empty($parent) )
228                 $category_parent = '0';
229             else
230                 $category_parent = category_exists($parent);
231
232             $catarr = compact('category_nicename', 'category_parent', 'posts_private', 'links_private', 'posts_private', 'cat_name');
233
234             $cat_ID = wp_insert_category($catarr);
235         }
236     }
237
238     function process_tags() {
239         global $wpdb;
240
241         $tag_names = (array) get_terms('post_tag', 'fields=names');
242
243         while ( $c = array_shift($this->tags) ) {
244             $tag_name = trim($this->get_tag( $c, 'wp:tag_name' ));
245
246             // If the category exists we leave it alone
247             if ( in_array($tag_name, $tag_names) )
248                 continue;
249
250             $slug = $this->get_tag( $c, 'wp:tag_slug' );
251             $description = $this->get_tag( $c, 'wp:tag_description' );
252
253             $tagarr = compact('slug', 'description');
254
255             $tag_ID = wp_insert_term($tag_name, 'post_tag', $tagarr);
256         }
257     }
258
259     function process_posts() {
260         $i = -1;
261         echo '<ol>';
262
263         foreach ($this->posts as $post) {
264             $result = $this->process_post($post);
265             if ( is_wp_error( $result ) )
266                 return $result;
267         }
268
269         echo '</ol>';
270
271         wp_import_cleanup($this->id);
272
273         echo '<h3>'.sprintf(__('All done.').' <a href="%s">'.__('Have fun!').'</a>', get_option('home')).'</h3>';
274     }
275
276     function process_post($post) {
277         global $wpdb;
278
279         $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
280           if ( $post_ID && !empty($this->posts_processed[$post_ID][1]) ) // Processed already
281             return 0;
282
283         // There are only ever one of these
284         $post_title     = $this->get_tag( $post, 'title' );
285         $post_date      = $this->get_tag( $post, 'wp:post_date' );
286         $post_date_gmt  = $this->get_tag( $post, 'wp:post_date_gmt' );
287         $comment_status = $this->get_tag( $post, 'wp:comment_status' );
288         $ping_status    = $this->get_tag( $post, 'wp:ping_status' );
289         $post_status    = $this->get_tag( $post, 'wp:status' );
290         $post_name      = $this->get_tag( $post, 'wp:post_name' );
291         $post_parent    = $this->get_tag( $post, 'wp:post_parent' );
292         $menu_order     = $this->get_tag( $post, 'wp:menu_order' );
293         $post_type      = $this->get_tag( $post, 'wp:post_type' );
294         $guid           = $this->get_tag( $post, 'guid' );
295         $post_author    = $this->get_tag( $post, 'dc:creator' );
296
297         $post_content = $this->get_tag( $post, 'content:encoded' );
298         $post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
299         $post_content = str_replace('<br>', '<br />', $post_content);
300         $post_content = str_replace('<hr>', '<hr />', $post_content);
301
302         preg_match_all('|<category domain="tag">(.*?)</category>|is', $post, $tags);
303         $tags = $tags[1];
304
305         $tag_index = 0;
306         foreach ($tags as $tag) {
307             $tags[$tag_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $tag)));
308             $tag_index++;
309         }
310
311         preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
312         $categories = $categories[1];
313
314         $cat_index = 0;
315         foreach ($categories as $category) {
316             $categories[$cat_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $category)));
317             $cat_index++;
318         }
319
320         if ($post_id = post_exists($post_title, '', $post_date)) {
321             echo '<li>';
322             printf(__('Post <i>%s</i> already exists.'), stripslashes($post_title));
323         } else {
324
325             // If it has parent, process parent first.
326             $post_parent = (int) $post_parent;
327             if ($parent = $this->posts_processed[$post_parent]) {
328                 if (!$parent[1]) {
329                     $result = $this->process_post($parent[0]); // If not yet, process the parent first.
330                     if ( is_wp_error( $result ) )
331                         return $result;
332                 }
333                 $post_parent = $parent[1]; // New ID of the parent;
334             }
335
336             echo '<li>';
337             printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
338
339             $post_author = $this->checkauthor($post_author); //just so that if a post already exists, new users are not created by checkauthor
340
341             $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');
342             $comment_post_ID = $post_id = wp_insert_post($postdata);
343             if ( is_wp_error( $post_id ) )
344                 return $post_id;
345
346             // Memorize old and new ID.
347             if ( $post_id && $post_ID && $this->posts_processed[$post_ID] )
348                 $this->posts_processed[$post_ID][1] = $post_id; // New ID.
349
350             // Add categories.
351             if (count($categories) > 0) {
352                 $post_cats = array();
353                 foreach ($categories as $category) {
354                     $slug = sanitize_term_field('slug', $category, 0, 'category', 'db');
355                     $cat = get_term_by('slug', $slug, 'category');
356                     $cat_ID = 0;
357                     if ( ! empty($cat) )
358                         $cat_ID = $cat->term_id;
359                     if ($cat_ID == 0) {
360                         $category = $wpdb->escape($category);
361                         $cat_ID = wp_insert_category(array('cat_name' => $category));
362                     }
363                     $post_cats[] = $cat_ID;
364                 }
365                 wp_set_post_categories($post_id, $post_cats);
366             }
367
368             // Add tags.
369             if (count($tags) > 0) {
370                 $post_tags = array();
371                 foreach ($tags as $tag) {
372                     $slug = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
373                     $tag_obj = get_term_by('slug', $slug, 'post_tag');
374                     $tag_id = 0;
375                     if ( ! empty($tag_obj) )
376                         $tag_id = $tag_obj->term_id;
377                     if ( $tag_id == 0 ) {
378                         $tag = $wpdb->escape($tag);
379                         $tag_id = wp_insert_term($tag, 'post_tag');
380                         $tag_id = $tag_id['term_id'];
381                     }
382                     $post_tags[] = $tag_id;
383                 }
384                 wp_set_post_tags($post_id, $post_tags);
385             }
386         }
387
388         // Now for comments
389         preg_match_all('|<wp:comment>(.*?)</wp:comment>|is', $post, $comments);
390         $comments = $comments[1];
391         $num_comments = 0;
392         if ( $comments) { foreach ($comments as $comment) {
393             $comment_author       = $this->get_tag( $comment, 'wp:comment_author');
394             $comment_author_email = $this->get_tag( $comment, 'wp:comment_author_email');
395             $comment_author_IP    = $this->get_tag( $comment, 'wp:comment_author_IP');
396             $comment_author_url   = $this->get_tag( $comment, 'wp:comment_author_url');
397             $comment_date         = $this->get_tag( $comment, 'wp:comment_date');
398             $comment_date_gmt     = $this->get_tag( $comment, 'wp:comment_date_gmt');
399             $comment_content      = $this->get_tag( $comment, 'wp:comment_content');
400             $comment_approved     = $this->get_tag( $comment, 'wp:comment_approved');
401             $comment_type         = $this->get_tag( $comment, 'wp:comment_type');
402             $comment_parent       = $this->get_tag( $comment, 'wp:comment_parent');
403
404             if ( !comment_exists($comment_author, $comment_date) ) {
405                 $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');
406                 wp_insert_comment($commentdata);
407                 $num_comments++;
408             }
409         } }
410
411         if ( $num_comments )
412             printf(' '.__('(%s comments)'), $num_comments);
413
414         // Now for post meta
415         preg_match_all('|<wp:postmeta>(.*?)</wp:postmeta>|is', $post, $postmeta);
416         $postmeta = $postmeta[1];
417         if ( $postmeta) { foreach ($postmeta as $p) {
418             $key   = $this->get_tag( $p, 'wp:meta_key' );
419             $value = $this->get_tag( $p, 'wp:meta_value' );
420             $value = stripslashes($value); // add_post_meta() will escape.
421             add_post_meta( $post_id, $key, $value );
422         } }
423     }
424
425     function import() {
426         $this->id = (int) $_GET['id'];
427
428         $this->file = <