Make WordPress Core

Ticket #6265: wordpress.php

File wordpress.php, 14.5 KB (added by jayminkapish, 17 years ago)

Wordpress Importer File

Line 
1<?php
2
3class 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_name, '', $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[] = intval( $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 = get_attached_file($this->id);
429                $this->get_authors_from_post();
430                $this->get_entries();
431                $this->process_categories();
432                $this->process_tags();
433                $result = $this->process_posts();
434                if ( is_wp_error( $result ) )
435                        return $result;
436        }
437
438        function dispatch() {
439                if (empty ($_GET['step']))
440                        $step = 0;
441                else
442                        $step = (int) $_GET['step'];
443
444                $this->header();
445                switch ($step) {
446                        case 0 :
447                                $this->greet();
448                                break;
449                        case 1 :
450                                check_admin_referer('import-upload');
451                                $this->select_authors();
452                                break;
453                        case 2:
454                                check_admin_referer('import-wordpress');
455                                $result = $this->import();
456                                if ( is_wp_error( $result ) )
457                                        echo $result->get_error_message();
458                                break;
459                }
460                $this->footer();
461        }
462
463        function WP_Import() {
464                // Nothing.
465        }
466}
467
468$wp_import = new WP_Import();
469
470register_importer('wordpress', 'WordPress', __('Import <strong>posts, comments, custom fields, pages, and categories</strong> from a WordPress export file'), array ($wp_import, 'dispatch'));
471
472?>