3 Add These Functions to make our lives easier
6 if(!function_exists('get_comment_count'))
8 function get_comment_count($post_ID)
11 return $wpdb->get_var( $wpdb->prepare("SELECT count(*) FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );
15 if(!function_exists('link_exists'))
17 function link_exists($linkname)
20 return $wpdb->get_var( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_name = %s", $linkname) );
25 The Main Importer Class
27 class Textpattern_Import {
31 echo '<div class="wrap">';
32 echo '<h2>'.__('Import Textpattern').'</h2>';
33 echo '<p>'.__('Steps may take a few minutes depending on the size of your database. Please be patient.').'</p>';
42 echo '<div class="narrow">';
43 echo '<p>'.__('Howdy! This imports categories, users, posts, comments, and links from any Textpattern 4.0.2+ into this blog.').'</p>';
44 echo '<p>'.__('This has not been tested on previous versions of Textpattern. Mileage may vary.').'</p>';
45 echo '<p>'.__('Your Textpattern Configuration settings are as follows:').'</p>';
46 echo '<form action="admin.php?import=textpattern&step=1" method="post">';
47 wp_nonce_field('import-textpattern');
49 echo '<p class="submit"><input type="submit" class="button" name="submit" value="'.attribute_escape(__('Import')).'" /></p>';
54 function get_txp_cats()
57 // General Housekeeping
58 $txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
59 set_magic_quotes_runtime(0);
60 $prefix = get_option('tpre');
63 return $txpdb->get_results('SELECT
67 FROM '.$prefix.'txp_category
68 WHERE type = "article"',
72 function get_txp_users()
75 // General Housekeeping
76 $txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
77 set_magic_quotes_runtime(0);
78 $prefix = get_option('tpre');
82 return $txpdb->get_results('SELECT
88 FROM '.$prefix.'txp_users', ARRAY_A);
91 function get_txp_posts()
93 // General Housekeeping
94 $txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
95 set_magic_quotes_runtime(0);
96 $prefix = get_option('tpre');
99 return $txpdb->get_results('SELECT
113 FROM '.$prefix.'textpattern
117 function get_txp_comments()
120 // General Housekeeping
121 $txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
122 set_magic_quotes_runtime(0);
123 $prefix = get_option('tpre');
126 return $txpdb->get_results('SELECT * FROM '.$prefix.'txp_discuss', ARRAY_A);
129 function get_txp_links()
131 //General Housekeeping
132 $txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
133 set_magic_quotes_runtime(0);
134 $prefix = get_option('tpre');
136 return $txpdb->get_results('SELECT
143 FROM '.$prefix.'txp_link',
147 function cat2wp($categories='')
149 // General Housekeeping
152 $txpcat2wpcat = array();
154 if(is_array($categories))
156 echo '<p>'.__('Importing Categories...').'<br /><br /></p>';
157 foreach ($categories as $category)
163 // Make Nice Variables
164 $name = $wpdb->escape($name);
165 $title = $wpdb->escape($title);
167 if($cinfo = category_exists($name))
169 $ret_id = wp_insert_category(array('cat_ID' => $cinfo, 'category_nicename' => $name, 'cat_name' => $title));
173 $ret_id = wp_insert_category(array('category_nicename' => $name, 'cat_name' => $title));
175 $txpcat2wpcat[$id] = $ret_id;
178 // Store category translation for future use
179 add_option('txpcat2wpcat',$txpcat2wpcat);
180 echo '<p>'.sprintf(__ngettext('Done! <strong>%1$s</strong> category imported.', 'Done! <strong>%1$s</strong> categories imported.', $count), $count).'<br /><br /></p>';
183 echo __('No Categories to Import!');
187 function users2wp($users='')
189 // General Housekeeping
192 $txpid2wpid = array();
197 echo '<p>'.__('Importing Users...').'<br /><br /></p>';
198 foreach($users as $user)
203 // Make Nice Variables
204 $name = $wpdb->escape($name);
205 $RealName = $wpdb->escape($RealName);
207 if($uinfo = get_userdatabylogin($name))
210 $ret_id = wp_insert_user(array(
212 'user_login' => $name,
213 'user_nicename' => $RealName,
214 'user_email' => $email,
215 'user_url' => 'http://',
216 'display_name' => $name)
221 $ret_id = wp_insert_user(array(
222 'user_login' => $name,
223 'user_nicename' => $RealName,
224 'user_email' => $email,
225 'user_url' => 'http://',
226 'display_name' => $name)
229 $txpid2wpid[$user_id] = $ret_id;
231 // Set Textpattern-to-WordPress permissions translation
232 $transperms = array(1 => '10', 2 => '9', 3 => '5', 4 => '4', 5 => '3', 6 => '2', 7 => '0');
234 // Update Usermeta Data
235 $user = new WP_User($ret_id);
236 if('10' == $transperms[$privs]) { $user->set_role('administrator'); }
237 if('9' == $transperms[$privs]) { $user->set_role('editor'); }
238 if('5' == $transperms[$privs]) { $user->set_role('editor'); }
239 if('4' == $transperms[$privs]) { $user->set_role('author'); }
240 if('3' == $transperms[$privs]) { $user->set_role('contributor'); }
241 if('2' == $transperms[$privs]) { $user->set_role('contributor'); }
242 if('0' == $transperms[$privs]) { $user->set_role('subscriber'); }
244 update_usermeta( $ret_id, 'wp_user_level', $transperms[$privs] );
245 update_usermeta( $ret_id, 'rich_editing', 'false');
246 }// End foreach($users as $user)
248 // Store id translation array for future use
249 add_option('txpid2wpid',$txpid2wpid);
252 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> users imported.'), $count).'<br /><br /></p>';
254 }// End if(is_array($users)
256 echo __('No Users to Import!');
259 }// End function user2wp()
261 function posts2wp($posts='')
263 // General Housekeeping
266 $txpposts2wpposts = array();
272 echo '<p>'.__('Importing Posts...').'<br /><br /></p>';
273 foreach($posts as $post)
278 // Set Textpattern-to-WordPress status translation
279 $stattrans = array(1 => 'draft', 2 => 'private', 3 => 'draft', 4 => 'publish', 5 => 'publish');
281 //Can we do this more efficiently?
282 $uinfo = ( get_userdatabylogin( $AuthorID ) ) ? get_userdatabylogin( $AuthorID ) : 1;
283 $authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
285 $Title = $wpdb->escape($Title);
286 $Body = $wpdb->escape($Body);
287 $Excerpt = $wpdb->escape($Excerpt);
288 $post_status = $stattrans[$Status];
290 // Import Post data into WordPress
292 if($pinfo = post_exists($Title,$Body))
294 $ret_id = wp_insert_post(array(
296 'post_date' => $Posted,
297 'post_date_gmt' => $post_date_gmt,
298 'post_author' => $authorid,
299 'post_modified' => $LastMod,
300 'post_modified_gmt' => $post_modified_gmt,
301 'post_title' => $Title,
302 'post_content' => $Body,
303 'post_excerpt' => $Excerpt,
304 'post_status' => $post_status,
305 'post_name' => $url_title,
306 'comment_count' => $comments_count)
308 if ( is_wp_error( $ret_id ) )
313 $ret_id = wp_insert_post(array(
314 'post_date' => $Posted,
315 'post_date_gmt' => $post_date_gmt,
316 'post_author' => $authorid,
317 'post_modified' => $LastMod,
318 'post_modified_gmt' => $post_modified_gmt,
319 'post_title' => $Title,
320 'post_content' => $Body,
321 'post_excerpt' => $Excerpt,
322 'post_status' => $post_status,
323 'post_name' => $url_title,
324 'comment_count' => $comments_count)
326 if ( is_wp_error( $ret_id ) )
329 $txpposts2wpposts[$ID] = $ret_id;
331 // Make Post-to-Category associations
333 $category1 = get_category_by_slug($Category1);
334 $category1 = $category1->term_id;
335 $category2 = get_category_by_slug($Category2);
336 $category2 = $category2->term_id;
337 if($cat1 = $category1) { $cats[1] = $cat1; }
338 if($cat2 = $category2) { $cats[2] = $cat2; }
340 if(!empty($cats)) { wp_set_post_categories($ret_id, $cats); }
343 // Store ID translation for later use
344 add_option('txpposts2wpposts',$txpposts2wpposts);
346 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> posts imported.'), $count).'<br /><br /></p>';
350 function comments2wp($comments='')
352 // General Housekeeping
355 $txpcm2wpcm = array();
356 $postarr = get_option('txpposts2wpposts');
359 if(is_array($comments))
361 echo '<p>'.__('Importing Comments...').'<br /><br /></p>';
362 foreach($comments as $comment)
368 $comment_ID = ltrim($discussid, '0');
369 $comment_post_ID = $postarr[$parentid];
370 $comment_approved = (1 == $visible) ? 1 : 0;
371 $name = $wpdb->escape($name);
372 $email = $wpdb->escape($email);
373 $web = $wpdb->escape($web);
374 $message = $wpdb->escape($message);
376 if($cinfo = comment_exists($name, $posted))
379 $ret_id = wp_update_comment(array(
380 'comment_ID' => $cinfo,
381 'comment_post_ID' => $comment_post_ID,
382 'comment_author' => $name,
383 'comment_author_email' => $email,
384 'comment_author_url' => $web,
385 'comment_date' => $posted,
386 'comment_content' => $message,
387 'comment_approved' => $comment_approved)
393 $ret_id = wp_insert_comment(array(
394 'comment_post_ID' => $comment_post_ID,
395 'comment_author' => $name,
396 'comment_author_email' => $email,
397 'comment_author_url' => $web,
398 'comment_author_IP' => $ip,
399 'comment_date' => $posted,
400 'comment_content' => $message,
401 'comment_approved' => $comment_approved)
404 $txpcm2wpcm[$comment_ID] = $ret_id;
406 // Store Comment ID translation for future use
407 add_option('txpcm2wpcm', $txpcm2wpcm);
409 // Associate newly formed categories with posts
410 get_comment_count($ret_id);
413 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
416 echo __('No Comments to Import!');
420 function links2wp($links='')
422 // General Housekeeping
426 // Deal with the links
429 echo '<p>'.__('Importing Links...').'<br /><br /></p>';
430 foreach($links as $link)
436 $category = $wpdb->escape($category);
437 $linkname = $wpdb->escape($linkname);
438 $description = $wpdb->escape($description);
440 if($linfo = link_exists($linkname))
442 $ret_id = wp_insert_link(array(
445 'link_name' => $linkname,
446 'link_category' => $category,
447 'link_description' => $description,
448 'link_updated' => $date)
453 $ret_id = wp_insert_link(array(
455 'link_name' => $linkname,
456 'link_category' => $category,
457 'link_description' => $description,
458 'link_updated' => $date)
461 $txplinks2wplinks[$link_id] = $ret_id;
463 add_option('txplinks2wplinks',$txplinks2wplinks);
465 printf(__ngettext('Done! <strong>%s</strong> link imported', 'Done! <strong>%s</strong> links imported', $count), $count);
466 echo '<br /><br /></p>';
469 echo __('No Links to Import!');
473 function import_categories()
476 $cats = $this->get_txp_cats();
477 $this->cat2wp($cats);
478 add_option('txp_cats', $cats);
482 echo '<form action="admin.php?import=textpattern&step=2" method="post">';
483 wp_nonce_field('import-textpattern');
484 printf('<input type="submit" class="button" name="submit" value="%s" />', attribute_escape(__('Import Users')));
489 function import_users()
492 $users = $this->get_txp_users();
493 $this->users2wp($users);
495 echo '<form action="admin.php?import=textpattern&step=3" method="post">';
496 wp_nonce_field('import-textpattern');
497 printf('<input type="submit" class="button" name="submit" value="%s" />', attribute_escape(__('Import Posts')));
501 function import_posts()
504 $posts = $this->get_txp_posts();
505 $result = $this->posts2wp($posts);
506 if ( is_wp_error( $result ) )
509 echo '<form action="admin.php?import=textpattern&step=4" method="post">';
510 wp_nonce_field('import-textpattern');
511 printf('<input type="submit" class="button" name="submit" value="%s" />', attribute_escape(__('Import Comments')));
515 function import_comments()
518 $comments = $this->get_txp_comments();
519 $this->comments2wp($comments);
521 echo '<form action="admin.php?import=textpattern&step=5" method="post">';
522 wp_nonce_field('import-textpattern');
523 printf('<input type="submit" class="button" name="submit" value="%s" />', attribute_escape(__('Import Links')));
527 function import_links()
530 $links = $this->get_txp_links();
531 $this->links2wp($links);
532 add_option('txp_links', $links);
534 echo '<form action="admin.php?import=textpattern&step=6" method="post">';
535 wp_nonce_field('import-textpattern');
536 printf('<input type="submit" class="button" name="submit" value="%s" />', attribute_escape(__('Finish')));
540 function cleanup_txpimport()
542 delete_option('tpre');
543 delete_option('txp_cats');
544 delete_option('txpid2wpid');
545 delete_option('txpcat2wpcat');
546 delete_option('txpposts2wpposts');
547 delete_option('txpcm2wpcm');
548 delete_option('txplinks2wplinks');
549 delete_option('txpuser');
550 delete_option('txppass');
551 delete_option('txpname');
552 delete_option('txphost');
553 do_action('import_done', 'textpattern');
559 echo '<p>'.__('Welcome to WordPress. We hope (and expect!) that you will find this platform incredibly rewarding! As a new WordPress user coming from Textpattern, there are some things that we would like to point out. Hopefully, they will help your transition go as smoothly as possible.').'</p>';
560 echo '<h3>'.__('Users').'</h3>';
561 echo '<p>'.sprintf(__('You have already setup WordPress and have been assigned an administrative login and password. Forget it. You didn’t have that login in Textpattern, why should you have it here? Instead we have taken care to import all of your users into our system. Unfortunately there is one downside. Because both WordPress and Textpattern uses a strong encryption hash with passwords, it is impossible to decrypt it and we are forced to assign temporary passwords to all your users. <strong>Every user has the same username, but their passwords are reset to password123.</strong> So <a href="%1$s">Login</a> and change it.'), get_bloginfo( 'wpurl' ) . '/wp-login.php').'</p>';
562 echo '<h3>'.__('Preserving Authors').'</h3>';
563 echo '<p>'.__('Secondly, we have attempted to preserve post authors. If you are the only author or contributor to your blog, then you are safe. In most cases, we are successful in this preservation endeavor. However, if we cannot ascertain the name of the writer due to discrepancies between database tables, we assign it to you, the administrative user.').'</p>';
564 echo '<h3>'.__('Textile').'</h3>';
565 echo '<p>'.__('Also, since you’re coming from Textpattern, you probably have been using Textile to format your comments and posts. If this is the case, we recommend downloading and installing <a href="http://www.huddledmasses.org/category/development/wordpress/textile/">Textile for WordPress</a>. Trust me... You’ll want it.').'</p>';
566 echo '<h3>'.__('WordPress Resources').'</h3>';
567 echo '<p>'.__('Finally, there are numerous WordPress resources around the internet. Some of them are:').'</p>';
569 echo '<li>'.__('<a href="http://www.wordpress.org">The official WordPress site</a>').'</li>';
570 echo '<li>'.__('<a href="http://wordpress.org/support/">The WordPress support forums</a>').'</li>';
571 echo '<li>'.__('<a href="http://codex.wordpress.org">The Codex (In other words, the WordPress Bible)</a>').'</li>';
573 echo '<p>'.sprintf(__('That’s it! What are you waiting for? Go <a href="%1$s">login</a>!'), get_bloginfo( 'wpurl' ) . '/wp-login.php').'</p>';
578 echo '<table class="form-table">';
579 printf('<tr><th scope="row"><label for="dbuser">%s</label></th><td><input type="text" name="dbuser" id="dbuser" /></td></tr>', __('Textpattern Database User:'));
580 printf('<tr><th scope="row"><label for="dbpass">%s</label></th><td><input type="password" name="dbpass" id="dbpass" /></td></tr>', __('Textpattern Database Password:'));
581 printf('<tr><th scope="row"><label for="dbname">%s</label></th><td><input type="text" id="dbname" name="dbname" /></td></tr>', __('Textpattern Database Name:'));
582 printf('<tr><th scope="row"><label for="dbhost">%s</label></th><td><input type="text" id="dbhost" name="dbhost" value="localhost" /></td></tr>', __('Textpattern Database Host:'));
583 printf('<tr><th scope="row"><label for="dbprefix">%s</label></th><td><input type="text" name="dbprefix" id="dbprefix" /></td></tr>', __('Textpattern Table prefix (if any):'));
590 if (empty ($_GET['step']))
593 $step = (int) $_GET['step'];
598 check_admin_referer('import-textpattern');
602 if(get_option('txpuser'))
603 delete_option('txpuser');
604 add_option('txpuser', sanitize_user($_POST['dbuser'], true));
608 if(get_option('txppass'))
609 delete_option('txppass');
610 add_option('txppass', sanitize_user($_POST['dbpass'], true));
615 if(get_option('txpname'))
616 delete_option('txpname');
617 add_option('txpname', sanitize_user($_POST['dbname'], true));
621 if(get_option('txphost'))
622 delete_option('txphost');
623 add_option('txphost', sanitize_user($_POST['dbhost'], true));
625 if($_POST['dbprefix'])
627 if(get_option('tpre'))
628 delete_option('tpre');
629 add_option('tpre', sanitize_user($_POST['dbprefix']));
642 $this->import_categories();
645 $this->import_users();
648 $result = $this->import_posts();
649 if ( is_wp_error( $result ) )
650 echo $result->get_error_message();
653 $this->import_comments();
656 $this->import_links();
659 $this->cleanup_txpimport();
666 function Textpattern_Import()
672 $txp_import = new Textpattern_Import();
673 register_importer('textpattern', __('Textpattern'), __('Import categories, users, posts, comments, and links from a Textpattern blog.'), array ($txp_import, 'dispatch'));