PluginProbe
Movable Type and TypePad Importer / 0.3
Movable Type and TypePad Importer v0.3
trunk 0.3 0.4 0.6 0.6.1 0.6.2 0.6.3 0.6.4
movabletype-importer / movabletype-importer.php

movabletype-importer.php in Movable Type and TypePad Importer 0.3, at movabletype-importer.php

534 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Movable Type and TypePad Importer
4 Plugin URI: http://wordpress.org/extend/plugins/movabletype-importer/
5 Description: Import posts and comments from a Movable Type or TypePad blog.
6 Author: wordpressdotorg
7 Author URI: http://wordpress.org/
8 Version: 0.3
9 Stable tag: 0.3
10 License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
11 */
12
13 if ( !defined('WP_LOAD_IMPORTERS') )
14 return;
15
16 // Load Importer API
17 require_once ABSPATH . 'wp-admin/includes/import.php';
18
19 if ( !class_exists( 'WP_Importer' ) ) {
20 $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
21 if ( file_exists( $class_wp_importer ) )
22 require_once $class_wp_importer;
23 }
24
25 /**
26 * Movable Type and TypePad Importer
27 *
28 * @package WordPress
29 * @subpackage Importer
30 */
31 if ( class_exists( 'WP_Importer' ) ) {
32 class MT_Import extends WP_Importer {
33
34 var $posts = array ();
35 var $file;
36 var $id;
37 var $mtnames = array ();
38 var $newauthornames = array ();
39 var $j = -1;
40
41 function header() {
42 echo '<div class="wrap">';
43 screen_icon();
44 echo '<h2>'.__('Import Movable Type or TypePad', 'movabletype-importer').'</h2>';
45 }
46
47 function footer() {
48 echo '</div>';
49 }
50
51 function greet() {
52 $this->header();
53 ?>
54 <div class="narrow">
55 <p><?php _e( 'Howdy! We are about to begin importing all of your Movable Type or TypePad entries into WordPress. To begin, either choose a file to upload and click &#8220;Upload file and import&#8221;, or use FTP to upload your MT export file as <code>mt-export.txt</code> in your <code>/wp-content/</code> directory and then click &#8220;Import mt-export.txt&#8221;.' , 'movabletype-importer'); ?></p>
56
57 <?php wp_import_upload_form( add_query_arg('step', 1) ); ?>
58 <form method="post" action="<?php echo esc_attr(add_query_arg('step', 1)); ?>" class="import-upload-form">
59
60 <?php wp_nonce_field('import-upload'); ?>
61 <p>
62 <input type="hidden" name="upload_type" value="ftp" />
63 <?php _e('Or use <code>mt-export.txt</code> in your <code>/wp-content/</code> directory', 'movabletype-importer'); ?></p>
64 <p class="submit">
65 <input type="submit" class="button" value="<?php esc_attr_e('Import mt-export.txt', 'movabletype-importer'); ?>" />
66 </p>
67 </form>
68 <p><?php _e('The importer is smart enough not to import duplicates, so you can run this multiple times without worry if&#8212;for whatever reason&#8212;it doesn&#8217;t finish. If you get an <strong>out of memory</strong> error try splitting up the import file into pieces.', 'movabletype-importer'); ?> </p>
69 </div>
70 <?php
71 $this->footer();
72 }
73
74 function users_form($n) {
75 $users = get_users_of_blog();
76 ?><select name="userselect[<?php echo $n; ?>]">
77 <option value="#NONE#"><?php _e('&mdash; Select &mdash;', 'movabletype-importer') ?></option>
78 <?php
79 foreach ( $users as $user )
80 echo '<option value="' . $user->user_login . '">' . $user->user_login . '</option>';
81 ?>
82 </select>
83 <?php
84 }
85
86 function has_gzip() {
87 return is_callable('gzopen');
88 }
89
90 function fopen($filename, $mode='r') {
91 if ( $this->has_gzip() )
92 return gzopen($filename, $mode);
93 return fopen($filename, $mode);
94 }
95
96 function feof($fp) {
97 if ( $this->has_gzip() )
98 return gzeof($fp);
99 return feof($fp);
100 }
101
102 function fgets($fp, $len=8192) {
103 if ( $this->has_gzip() )
104 return gzgets($fp, $len);
105 return fgets($fp, $len);
106 }
107
108 function fclose($fp) {
109 if ( $this->has_gzip() )
110 return gzclose($fp);
111 return fclose($fp);
112 }
113
114 //function to check the authorname and do the mapping
115 function checkauthor($author) {
116 //mtnames is an array with the names in the mt import file
117 $pass = wp_generate_password();
118 if (!(in_array($author, $this->mtnames))) { //a new mt author name is found
119 ++ $this->j;
120 $this->mtnames[$this->j] = $author; //add that new mt author name to an array
121 $user_id = username_exists($this->newauthornames[$this->j]); //check if the new author name defined by the user is a pre-existing wp user
122 if (!$user_id) { //banging my head against the desk now.
123 if ($this->newauthornames[$this->j] == 'left_blank') { //check if the user does not want to change the authorname
124 $user_id = wp_create_user($author, $pass);
125 $this->newauthornames[$this->j] = $author; //now we have a name, in the place of left_blank.
126 } else {
127 $user_id = wp_create_user($this->newauthornames[$this->j], $pass);
128 }
129 } else {
130 return $user_id; // return pre-existing wp username if it exists
131 }
132 } else {
133 $key = array_search($author, $this->mtnames); //find the array key for $author in the $mtnames array
134 $user_id = username_exists($this->newauthornames[$key]); //use that key to get the value of the author's name from $newauthornames
135 }
136
137 return $user_id;
138 }
139
140 function get_mt_authors() {
141 $temp = array();
142 $authors = array();
143
144 $handle = $this->fopen($this->file, 'r');
145 if ( $handle == null )
146 return false;
147
148 $in_comment = false;
149 while ( $line = $this->fgets($handle) ) {
150 $line = trim($line);
151
152 if ( 'COMMENT:' == $line )
153 $in_comment = true;
154 else if ( '-----' == $line )
155 $in_comment = false;
156
157 if ( $in_comment || 0 !== strpos($line,"AUTHOR:") )
158 continue;
159
160 $temp[] = trim( substr($line, strlen("AUTHOR:")) );
161 }
162
163 //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.
164 $authors[0] = array_shift($temp);
165 $y = count($temp) + 1;
166 for ($x = 1; $x < $y; $x ++) {
167 $next = array_shift($temp);
168 if (!(in_array($next, $authors)))
169 array_push($authors, $next);
170 }
171
172 $this->fclose($handle);
173
174 return $authors;
175 }
176
177 function get_authors_from_post() {
178 $formnames = array ();
179 $selectnames = array ();
180
181 foreach ($_POST['user'] as $key => $line) {
182 $newname = trim(stripslashes($line));
183 if ($newname == '')
184 $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.
185 array_push($formnames, $newname);
186 } // $formnames is the array with the form entered names
187
188 foreach ($_POST['userselect'] as $user => $key) {
189 $selected = trim(stripslashes($key));
190 array_push($selectnames, $selected);
191 }
192
193 $count = count($formnames);
194 for ($i = 0; $i < $count; $i ++) {
195 if ($selectnames[$i] != '#NONE#') { //if no name was selected from the select menu, use the name entered in the form
196 array_push($this->newauthornames, "$selectnames[$i]");
197 } else {
198 array_push($this->newauthornames, "$formnames[$i]");
199 }
200 }
201 }
202
203 function mt_authors_form() {
204 ?>
205 <div class="wrap">
206 <?php screen_icon(); ?>
207 <h2><?php _e('Assign Authors', 'movabletype-importer'); ?></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 admin&#8217;s entries.', 'movabletype-importer'); ?></p>
209 <p><?php _e('Below, you can see the names of the authors of the MovableType posts in <em>italics</em>. For each of these names, you can either pick an author in your WordPress installation from the menu, or enter a name for the author in the textbox.', 'movabletype-importer'); ?></p>
210 <p><?php _e('If a new user is created by WordPress, a password will be randomly generated. Manually change the user&#8217;s details if necessary.', 'movabletype-importer'); ?></p>
211 <?php
212
213
214 $authors = $this->get_mt_authors();
215 echo '<ol id="authors">';
216 echo '<form action="?import=mt&amp;step=2&amp;id=' . $this->id . '" method="post">';
217 wp_nonce_field('import-mt');
218 $j = -1;
219 foreach ($authors as $author) {
220 ++ $j;
221 echo '<li><label>'.__('Current author:', 'movabletype-importer').' <strong>'.$author.'</strong><br />'.sprintf(__('Create user %1$s or map to existing', 'movabletype-importer'), ' <input type="text" value="'. esc_attr($author) .'" name="'.'user[]'.'" maxlength="30"> <br />');
222 $this->users_form($j);
223 echo '</label></li>';
224 }
225
226 echo '<p class="submit"><input type="submit" class="button" value="'.esc_attr__('Submit', 'movabletype-importer').'"></p>'.'<br />';
227 echo '</form>';
228 echo '</ol></div>';
229
230 }
231
232 function select_authors() {
233 if ( $_POST['upload_type'] === 'ftp' ) {
234 $file['file'] = WP_CONTENT_DIR . '/mt-export.txt';
235 if ( !file_exists($file['file']) )
236 $file['error'] = __('<code>mt-export.txt</code> does not exist', 'movabletype-importer');
237 } else {
238 $file = wp_import_handle_upload();
239 }
240 if ( isset($file['error']) ) {
241 $this->header();
242 echo '<p>'.__('Sorry, there has been an error', 'movabletype-importer').'.</p>';
243 echo '<p><strong>' . $file['error'] . '</strong></p>';
244 $this->footer();
245 return;
246 }
247 $this->file = $file['file'];
248 $this->id = (int) $file['id'];
249
250 $this->mt_authors_form();
251 }
252
253 function save_post(&$post, &$comments, &$pings) {
254 $post = get_object_vars($post);
255 $post = add_magic_quotes($post);
256 $post = (object) $post;
257
258 if ( $post_id = post_exists($post->post_title, '', $post->post_date) ) {
259 echo '<li>';
260 printf(__('Post <em>%s</em> already exists.', 'movabletype-importer'), stripslashes($post->post_title));
261 } else {
262 echo '<li>';
263 printf(__('Importing post <em>%s</em>...', 'movabletype-importer'), stripslashes($post->post_title));
264
265 if ( '' != trim( $post->extended ) )
266 $post->post_content .= "\n<!--more-->\n$post->extended";
267
268 $post->post_author = $this->checkauthor($post->post_author); //just so that if a post already exists, new users are not created by checkauthor
269 $post_id = wp_insert_post($post);
270 if ( is_wp_error( $post_id ) )
271 return $post_id;
272
273 // Add categories.
274 if ( 0 != count($post->categories) ) {
275 wp_create_categories($post->categories, $post_id);
276 }
277
278 // Add tags or keywords
279 if ( 1 < strlen($post->post_keywords) ) {
280 // Keywords exist.
281 printf('<br />'.__('Adding tags <em>%s</em>...', 'movabletype-importer'), stripslashes($post->post_keywords));
282 wp_add_post_tags($post_id, $post->post_keywords);
283 }
284 }
285
286 $num_comments = 0;
287 foreach ( $comments as $comment ) {
288 $comment = get_object_vars($comment);
289 $comment = add_magic_quotes($comment);
290
291 if ( !comment_exists($comment['comment_author'], $comment['comment_date'])) {
292 $comment['comment_post_ID'] = $post_id;
293 $comment = wp_filter_comment($comment);
294 wp_insert_comment($comment);
295 $num_comments++;
296 }
297 }
298
299 if ( $num_comments )
300 printf(' '._n('(%s comment)', '(%s comments)', $num_comments, 'movabletype-importer'), $num_comments);
301
302 $num_pings = 0;
303 foreach ( $pings as $ping ) {
304 $ping = get_object_vars($ping);
305 $ping = add_magic_quotes($ping);
306
307 if ( !comment_exists($ping['comment_author'], $ping['comment_date'])) {
308 $ping['comment_content'] = "<strong>{$ping['title']}</strong>\n\n{$ping['comment_content']}";
309 $ping['comment_post_ID'] = $post_id;
310 $ping = wp_filter_comment($ping);
311 wp_insert_comment($ping);
312 $num_pings++;
313 }
314 }
315
316 if ( $num_pings )
317 printf(' '._n('(%s ping)', '(%s pings)', $num_pings, 'movabletype-importer'), $num_pings);
318
319 echo "</li>";
320 //ob_flush();flush();
321 }
322
323 function process_posts() {
324 global $wpdb;
325
326 $handle = $this->fopen($this->file, 'r');
327 if ( $handle == null )
328 return false;
329
330 $context = '';
331 $post = new StdClass();
332 $comment = new StdClass();
333 $comments = array();
334 $ping = new StdClass();
335 $pings = array();
336
337 echo "<div class='wrap'><ol>";
338
339 while ( $line = $this->fgets($handle) ) {
340 $line = trim($line);
341
342 if ( '-----' == $line ) {
343 // Finishing a multi-line field
344 if ( 'comment' == $context ) {
345 $comments[] = $comment;
346 $comment = new StdClass();
347 } else if ( 'ping' == $context ) {
348 $pings[] = $ping;
349 $ping = new StdClass();
350 }
351 $context = '';
352 } else if ( '--------' == $line ) {
353 // Finishing a post.
354 $context = '';
355 $result = $this->save_post($post, $comments, $pings);
356 if ( is_wp_error( $result ) )
357 return $result;
358 $post = new StdClass;
359 $comment = new StdClass();
360 $ping = new StdClass();
361 $comments = array();
362 $pings = array();
363 } else if ( 'BODY:' == $line ) {
364 $context = 'body';
365 } else if ( 'EXTENDED BODY:' == $line ) {
366 $context = 'extended';
367 } else if ( 'EXCERPT:' == $line ) {
368 $context = 'excerpt';
369 } else if ( 'KEYWORDS:' == $line ) {
370 $context = 'keywords';
371 } else if ( 'COMMENT:' == $line ) {
372 $context = 'comment';
373 } else if ( 'PING:' == $line ) {
374 $context = 'ping';
375 } else if ( 0 === strpos($line, "AUTHOR:") ) {
376 $author = trim( substr($line, strlen("AUTHOR:")) );
377 if ( '' == $context )
378 $post->post_author = $author;
379 else if ( 'comment' == $context )
380 $comment->comment_author = $author;
381 } else if ( 0 === strpos($line, "TITLE:") ) {
382 $title = trim( substr($line, strlen("TITLE:")) );
383 if ( '' == $context )
384 $post->post_title = $title;
385 else if ( 'ping' == $context )
386 $ping->title = $title;
387 } else if ( 0 === strpos($line, "STATUS:") ) {
388 $status = trim( strtolower( substr($line, strlen("STATUS:")) ) );
389 if ( empty($status) )
390 $status = 'publish';
391 $post->post_status = $status;
392 } else if ( 0 === strpos($line, "ALLOW COMMENTS:") ) {
393 $allow = trim( substr($line, strlen("ALLOW COMMENTS:")) );
394 if ( $allow == 1 )
395 $post->comment_status = 'open';
396 else
397 $post->comment_status = 'closed';
398 } else if ( 0 === strpos($line, "ALLOW PINGS:") ) {
399 $allow = trim( substr($line, strlen("ALLOW PINGS:")) );
400 if ( $allow == 1 )
401 $post->ping_status = 'open';
402 else
403 $post->ping_status = 'closed';
404 } else if ( 0 === strpos($line, "CATEGORY:") ) {
405 $category = trim( substr($line, strlen("CATEGORY:")) );
406 if ( '' != $category )
407 $post->categories[] = $category;
408 } else if ( 0 === strpos($line, "PRIMARY CATEGORY:") ) {
409 $category = trim( substr($line, strlen("PRIMARY CATEGORY:")) );
410 if ( '' != $category )
411 $post->categories[] = $category;
412 } else if ( 0 === strpos($line, "DATE:") ) {
413 $date = trim( substr($line, strlen("DATE:")) );
414 $date = strtotime($date);
415 $date = date('Y-m-d H:i:s', $date);
416 $date_gmt = get_gmt_from_date($date);
417 if ( '' == $context ) {
418 $post->post_modified = $date;
419 $post->post_modified_gmt = $date_gmt;
420 $post->post_date = $date;
421 $post->post_date_gmt = $date_gmt;
422 } else if ( 'comment' == $context ) {
423 $comment->comment_date = $date;
424 } else if ( 'ping' == $context ) {
425 $ping->comment_date = $date;
426 }
427 } else if ( 0 === strpos($line, "EMAIL:") ) {
428 $email = trim( substr($line, strlen("EMAIL:")) );
429 if ( 'comment' == $context )
430 $comment->comment_author_email = $email;
431 else
432 $ping->comment_author_email = '';
433 } else if ( 0 === strpos($line, "IP:") ) {
434 $ip = trim( substr($line, strlen("IP:")) );
435 if ( 'comment' == $context )
436 $comment->comment_author_IP = $ip;
437 else
438 $ping->comment_author_IP = $ip;
439 } else if ( 0 === strpos($line, "URL:") ) {
440 $url = trim( substr($line, strlen("URL:")) );
441 if ( 'comment' == $context )
442 $comment->comment_author_url = $url;
443 else
444 $ping->comment_author_url = $url;
445 } else if ( 0 === strpos($line, "BLOG NAME:") ) {
446 $blog = trim( substr($line, strlen("BLOG NAME:")) );
447 $ping->comment_author = $blog;
448 } else if ( 0 === strpos($line, "BASENAME:") ) {
449 $post_name = trim( substr($line, strlen("BASENAME:")) );
450 $post->post_name = $post_name;
451 } else {
452 // Processing multi-line field, check context.
453
454 if( !empty($line) )
455 $line .= "\n";
456
457 if ( 'body' == $context ) {
458 $post->post_content .= $line;
459 } else if ( 'extended' == $context ) {
460 $post->extended .= $line;
461 } else if ( 'excerpt' == $context ) {
462 $post->post_excerpt .= $line;
463 } else if ( 'keywords' == $context ) {
464 $post->post_keywords .= $line;
465 } else if ( 'comment' == $context ) {
466 $comment->comment_content .= $line;
467 } else if ( 'ping' == $context ) {
468 $ping->comment_content .= $line;
469 }
470 }
471 }
472
473 $this->fclose($handle);
474
475 echo '</ol>';
476
477 wp_import_cleanup($this->id);
478 do_action('import_done', 'mt');
479
480 echo '<h3>'.sprintf(__('All done. <a href="%s">Have fun!</a>', 'movabletype-importer'), get_option('home')).'</h3></div>';
481 }
482
483 function import() {
484 $this->id = (int) $_GET['id'];
485 if ( $this->id == 0 )
486 $this->file = WP_CONTENT_DIR . '/mt-export.txt';
487 else
488 $this->file = get_attached_file($this->id);
489 $this->get_authors_from_post();
490 $result = $this->process_posts();
491 if ( is_wp_error( $result ) )
492 return $result;
493 }
494
495 function dispatch() {
496 if (empty ($_GET['step']))
497 $step = 0;
498 else
499 $step = (int) $_GET['step'];
500
501 switch ($step) {
502 case 0 :
503 $this->greet();
504 break;
505 case 1 :
506 check_admin_referer('import-upload');
507 $this->select_authors();
508 break;
509 case 2:
510 check_admin_referer('import-mt');
511 set_time_limit(0);
512 $result = $this->import();
513 if ( is_wp_error( $result ) )
514 echo $result->get_error_message();
515 break;
516 }
517 }
518
519 function MT_Import() {
520 // Nothing.
521 }
522 }
523
524 $mt_import = new MT_Import();
525
526 register_importer('mt', __('Movable Type and TypePad', 'movabletype-importer'), __('Import posts and comments from a Movable Type or TypePad blog.', 'movabletype-importer'), array ($mt_import, 'dispatch'));
527
528 } // class_exists( 'WP_Importer' )
529
530 function movabletype_importer_init() {
531 load_plugin_textdomain( 'movabletype-importer', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
532 }
533 add_action( 'init', 'movabletype_importer_init' );
534