7 * @author Thomas Quinot
8 * @link http://thomas.quinot.org/
12 Add These Functions to make our lives easier
15 if(!function_exists('get_comment_count'))
18 * Get the comment count for posts.
21 * @subpackage Dotclear_Import
23 * @param int $post_ID Post ID
26 function get_comment_count($post_ID)
29 return $wpdb->get_var( $wpdb->prepare("SELECT count(*) FROM $wpdb->comments WHERE comment_post_ID = %d", $post_ID) );
33 if(!function_exists('link_exists'))
36 * Check whether link already exists.
39 * @subpackage Dotclear_Import
41 * @param string $linkname
44 function link_exists($linkname)
47 return $wpdb->get_var( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_name = %s", $linkname) );
52 * Convert from dotclear charset to utf8 if required
55 * @subpackage Dotclear_Import
61 if (seems_utf8 ($s)) {
64 return iconv(get_option ("dccharset"),"UTF-8",$s);
70 * @subpackage Dotclear_Import
75 function textconv ($s) {
76 return csc (preg_replace ('|(?<!<br />)\s*\n|', ' ', $s));
80 * Dotclear Importer class
82 * Will process the WordPress eXtended RSS files that you upload from the export
86 * @subpackage Importer
90 class Dotclear_Import {
94 echo '<div class="wrap">';
96 echo '<h2>'.__('Import DotClear').'</h2>';
97 echo '<p>'.__('Steps may take a few minutes depending on the size of your database. Please be patient.').'</p>';
107 echo '<div class="narrow"><p>'.__('Howdy! This importer allows you to extract posts from a DotClear database into your blog. Mileage may vary.').'</p>';
108 echo '<p>'.__('Your DotClear Configuration settings are as follows:').'</p>';
109 echo '<form action="admin.php?import=dotclear&step=1" method="post">';
110 wp_nonce_field('import-dotclear');
112 echo '<p class="submit"><input type="submit" name="submit" class="button" value="'.esc_attr__('Import Categories').'" /></p>';
113 echo '</form></div>';
116 function get_dc_cats()
119 // General Housekeeping
120 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
121 set_magic_quotes_runtime(0);
122 $dbprefix = get_option('dcdbprefix');
125 return $dcdb->get_results('SELECT * FROM '.$dbprefix.'categorie', ARRAY_A);
128 function get_dc_users()
131 // General Housekeeping
132 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
133 set_magic_quotes_runtime(0);
134 $dbprefix = get_option('dcdbprefix');
138 return $dcdb->get_results('SELECT * FROM '.$dbprefix.'user', ARRAY_A);
141 function get_dc_posts()
143 // General Housekeeping
144 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
145 set_magic_quotes_runtime(0);
146 $dbprefix = get_option('dcdbprefix');
149 return $dcdb->get_results('SELECT '.$dbprefix.'post.*, '.$dbprefix.'categorie.cat_libelle_url AS post_cat_name
150 FROM '.$dbprefix.'post INNER JOIN '.$dbprefix.'categorie
151 ON '.$dbprefix.'post.cat_id = '.$dbprefix.'categorie.cat_id', ARRAY_A);
154 function get_dc_comments()
157 // General Housekeeping
158 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
159 set_magic_quotes_runtime(0);
160 $dbprefix = get_option('dcdbprefix');
163 return $dcdb->get_results('SELECT * FROM '.$dbprefix.'comment', ARRAY_A);
166 function get_dc_links()
168 //General Housekeeping
169 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
170 set_magic_quotes_runtime(0);
171 $dbprefix = get_option('dcdbprefix');
173 return $dcdb->get_results('SELECT * FROM '.$dbprefix.'link ORDER BY position', ARRAY_A);
176 function cat2wp($categories='')
178 // General Housekeeping
181 $dccat2wpcat = array();
183 if(is_array($categories))
185 echo '<p>'.__('Importing Categories...').'<br /><br /></p>';
186 foreach ($categories as $category)
191 // Make Nice Variables
192 $name = $wpdb->escape($cat_libelle_url);
193 $title = $wpdb->escape(csc ($cat_libelle));
194 $desc = $wpdb->escape(csc ($cat_desc));
196 if($cinfo = category_exists($name))
198 $ret_id = wp_insert_category(array('cat_ID' => $cinfo, 'category_nicename' => $name, 'cat_name' => $title, 'category_description' => $desc));
202 $ret_id = wp_insert_category(array('category_nicename' => $name, 'cat_name' => $title, 'category_description' => $desc));
204 $dccat2wpcat[$id] = $ret_id;
207 // Store category translation for future use
208 add_option('dccat2wpcat',$dccat2wpcat);
209 echo '<p>'.sprintf(_n('Done! <strong>%1$s</strong> category imported.', 'Done! <strong>%1$s</strong> categories imported.', $count), $count).'<br /><br /></p>';
212 echo __('No Categories to Import!');
216 function users2wp($users='')
218 // General Housekeeping
221 $dcid2wpid = array();
226 echo '<p>'.__('Importing Users...').'<br /><br /></p>';
227 foreach($users as $user)
232 // Make Nice Variables
233 $name = $wpdb->escape(csc ($name));
234 $RealName = $wpdb->escape(csc ($user_pseudo));
236 if($uinfo = get_userdatabylogin($name))
239 $ret_id = wp_insert_user(array(
241 'user_login' => $user_id,
242 'user_nicename' => $Realname,
243 'user_email' => $user_email,
244 'user_url' => 'http://',
245 'display_name' => $Realname)
250 $ret_id = wp_insert_user(array(
251 'user_login' => $user_id,
252 'user_nicename' => csc ($user_pseudo),
253 'user_email' => $user_email,
254 'user_url' => 'http://',
255 'display_name' => $Realname)
258 $dcid2wpid[$user_id] = $ret_id;
260 // Set DotClear-to-WordPress permissions translation
262 // Update Usermeta Data
263 $user = new WP_User($ret_id);
264 $wp_perms = $user_level + 1;
265 if(10 == $wp_perms) { $user->set_role('administrator'); }
266 else if(9 == $wp_perms) { $user->set_role('editor'); }
267 else if(5 <= $wp_perms) { $user->set_role('editor'); }
268 else if(4 <= $wp_perms) { $user->set_role('author'); }
269 else if(3 <= $wp_perms) { $user->set_role('contributor'); }
270 else if(2 <= $wp_perms) { $user->set_role('contributor'); }
271 else { $user->set_role('subscriber'); }
273 update_usermeta( $ret_id, 'wp_user_level', $wp_perms);
274 update_usermeta( $ret_id, 'rich_editing', 'false');
275 update_usermeta( $ret_id, 'first_name', csc ($user_prenom));
276 update_usermeta( $ret_id, 'last_name', csc ($user_nom));
277 }// End foreach($users as $user)
279 // Store id translation array for future use
280 add_option('dcid2wpid',$dcid2wpid);
283 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> users imported.'), $count).'<br /><br /></p>';
285 }// End if(is_array($users)
287 echo __('No Users to Import!');
290 }// End function user2wp()
292 function posts2wp($posts='')
294 // General Housekeeping
297 $dcposts2wpposts = array();
303 echo '<p>'.__('Importing Posts...').'<br /><br /></p>';
304 foreach($posts as $post)
309 // Set DotClear-to-WordPress status translation
310 $stattrans = array(0 => 'draft', 1 => 'publish');
311 $comment_status_map = array (0 => 'closed', 1 => 'open');
313 //Can we do this more efficiently?
314 $uinfo = ( get_userdatabylogin( $user_id ) ) ? get_userdatabylogin( $user_id ) : 1;
315 $authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
317 $Title = $wpdb->escape(csc ($post_titre));
318 $post_content = textconv ($post_content);
320 if ($post_chapo != "") {
321 $post_excerpt = textconv ($post_chapo);
322 $post_content = $post_excerpt ."\n<!--more-->\n".$post_content;
324 $post_excerpt = $wpdb->escape ($post_excerpt);
325 $post_content = $wpdb->escape ($post_content);
326 $post_status = $stattrans[$post_pub];
328 // Import Post data into WordPress
330 if($pinfo = post_exists($Title,$post_content))
332 $ret_id = wp_insert_post(array(
334 'post_author' => $authorid,
335 'post_date' => $post_dt,
336 'post_date_gmt' => $post_dt,
337 'post_modified' => $post_upddt,
338 'post_modified_gmt' => $post_upddt,
339 'post_title' => $Title,
340 'post_content' => $post_content,
341 'post_excerpt' => $post_excerpt,
342 'post_status' => $post_status,
343 'post_name' => $post_titre_url,
344 'comment_status' => $comment_status_map[$post_open_comment],
345 'ping_status' => $comment_status_map[$post_open_tb],
346 'comment_count' => $post_nb_comment + $post_nb_trackback)
348 if ( is_wp_error( $ret_id ) )
353 $ret_id = wp_insert_post(array(
354 'post_author' => $authorid,
355 'post_date' => $post_dt,
356 'post_date_gmt' => $post_dt,
357 'post_modified' => $post_modified_gmt,
358 'post_modified_gmt' => $post_modified_gmt,
359 'post_title' => $Title,
360 'post_content' => $post_content,
361 'post_excerpt' => $post_excerpt,
362 'post_status' => $post_status,
363 'post_name' => $post_titre_url,
364 'comment_status' => $comment_status_map[$post_open_comment],
365 'ping_status' => $comment_status_map[$post_open_tb],
366 'comment_count' => $post_nb_comment + $post_nb_trackback)
368 if ( is_wp_error( $ret_id ) )
371 $dcposts2wpposts[$post_id] = $ret_id;
373 // Make Post-to-Category associations
375 $category1 = get_category_by_slug($post_cat_name);
376 $category1 = $category1->term_id;
378 if($cat1 = $category1) { $cats[1] = $cat1; }
380 if(!empty($cats)) { wp_set_post_categories($ret_id, $cats); }
383 // Store ID translation for later use
384 add_option('dcposts2wpposts',$dcposts2wpposts);
386 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> posts imported.'), $count).'<br /><br /></p>';
390 function comments2wp($comments='')
392 // General Housekeeping
395 $dccm2wpcm = array();
396 $postarr = get_option('dcposts2wpposts');
399 if(is_array($comments))
401 echo '<p>'.__('Importing Comments...').'<br /><br /></p>';
402 foreach($comments as $comment)
408 $comment_ID = (int) ltrim($comment_id, '0');
409 $comment_post_ID = (int) $postarr[$post_id];
410 $comment_approved = "$comment_pub";
411 $name = $wpdb->escape(csc ($comment_auteur));
412 $email = $wpdb->escape($comment_email);
413 $web = "http://".$wpdb->escape($comment_site);
414 $message = $wpdb->escape(textconv ($comment_content));
416 if($cinfo = comment_exists($name, $comment_dt))
419 $ret_id = wp_update_comment(array(
420 'comment_ID' => $cinfo,
421 'comment_post_ID' => $comment_post_ID,
422 'comment_author' => $name,
423 'comment_author_email' => $email,
424 'comment_author_url' => $web,
425 'comment_author_IP' => $comment_ip,
426 'comment_date' => $comment_dt,
427 'comment_date_gmt' => $comment_dt,
428 'comment_content' => $message,
429 'comment_approved' => $comment_approved)
435 $ret_id = wp_insert_comment(array(
436 'comment_post_ID' => $comment_post_ID,
437 'comment_author' => $name,
438 'comment_author_email' => $email,
439 'comment_author_url' => $web,
440 'comment_author_IP' => $comment_ip,
441 'comment_date' => $comment_dt,
442 'comment_date_gmt' => $comment_dt,
443 'comment_content' => $message,
444 'comment_approved' => $comment_approved)
447 $dccm2wpcm[$comment_ID] = $ret_id;
449 // Store Comment ID translation for future use
450 add_option('dccm2wpcm', $dccm2wpcm);
452 // Associate newly formed categories with posts
453 get_comment_count($ret_id);
456 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
459 echo __('No Comments to Import!');
463 function links2wp($links='')
465 // General Housekeeping
469 // Deal with the links
472 echo '<p>'.__('Importing Links...').'<br /><br /></p>';
473 foreach($links as $link)
479 if ($cinfo = is_term(csc ($title), 'link_category')) {
480 $category = $cinfo['term_id'];
482 $category = wp_insert_term($wpdb->escape (csc ($title)), 'link_category');
483 $category = $category['term_id'];
486 $linkname = $wpdb->escape(csc ($label));
487 $description = $wpdb->escape(csc ($title));
489 if($linfo = link_exists($linkname)) {
490 $ret_id = wp_insert_link(array(
493 'link_name' => $linkname,
494 'link_category' => $category,
495 'link_description' => $description)
498 $ret_id = wp_insert_link(array(
500 'link_name' => $linkname,
501 'link_category' => $category,
502 'link_description' => $description)
505 $dclinks2wplinks[$link_id] = $ret_id;
508 add_option('dclinks2wplinks',$dclinks2wplinks);
510 printf(_n('Done! <strong>%s</strong> link or link category imported.', 'Done! <strong>%s</strong> links or link categories imported.', $count), $count);
511 echo '<br /><br /></p>';
514 echo __('No Links to Import!');
518 function import_categories()
521 $cats = $this->get_dc_cats();
522 $this->cat2wp($cats);
523 add_option('dc_cats', $cats);
527 echo '<form action="admin.php?import=dotclear&step=2" method="post">';
528 wp_nonce_field('import-dotclear');
529 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Users'));
534 function import_users()
537 $users = $this->get_dc_users();
538 $this->users2wp($users);
540 echo '<form action="admin.php?import=dotclear&step=3" method="post">';
541 wp_nonce_field('import-dotclear');
542 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Posts'));
546 function import_posts()
549 $posts = $this->get_dc_posts();
550 $result = $this->posts2wp($posts);
551 if ( is_wp_error( $result ) )
554 echo '<form action="admin.php?import=dotclear&step=4" method="post">';
555 wp_nonce_field('import-dotclear');
556 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Comments'));
560 function import_comments()
563 $comments = $this->get_dc_comments();
564 $this->comments2wp($comments);
566 echo '<form action="admin.php?import=dotclear&step=5" method="post">';
567 wp_nonce_field('import-dotclear');
568 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Links'));
572 function import_links()
575 $links = $this->get_dc_links();
576 $this->links2wp($links);
577 add_option('dc_links', $links);
579 echo '<form action="admin.php?import=dotclear&step=6" method="post">';
580 wp_nonce_field('import-dotclear');
581 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Finish'));
585 function cleanup_dcimport()
587 delete_option('dcdbprefix');
588 delete_option('dc_cats');
589 delete_option('dcid2wpid');
590 delete_option('dccat2wpcat');
591 delete_option('dcposts2wpposts');
592 delete_option('dccm2wpcm');
593 delete_option('dclinks2wplinks');
594 delete_option('dcuser');
595 delete_option('dcpass');
596 delete_option('dcname');
597 delete_option('dchost');
598 delete_option('dccharset');
599 do_action('import_done', 'dotclear');
605 echo '<p>'.__('Welcome to WordPress. We hope (and expect!) that you will find this platform incredibly rewarding! As a new WordPress user coming from DotClear, there are some things that we would like to point out. Hopefully, they will help your transition go as smoothly as possible.').'</p>';
606 echo '<h3>'.__('Users').'</h3>';
607 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 DotClear, 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 DotClear 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.'), '/wp-login.php').'</p>';
608 echo '<h3>'.__('Preserving Authors').'</h3>';
609 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>';
610 echo '<h3>'.__('Textile').'</h3>';
611 echo '<p>'.__('Also, since you’re coming from DotClear, 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>';
612 echo '<h3>'.__('WordPress Resources').'</h3>';
613 echo '<p>'.__('Finally, there are numerous WordPress resources around the internet. Some of them are:').'</p>';
615 echo '<li>'.__('<a href="http://www.wordpress.org">The official WordPress site</a>').'</li>';
616 echo '<li>'.__('<a href="http://wordpress.org/support/">The WordPress support forums</a>').'</li>';
617 echo '<li>'.__('<a href="http://codex.wordpress.org">The Codex (In other words, the WordPress Bible)</a>').'</li>';
619 echo '<p>'.sprintf(__('That’s it! What are you waiting for? Go <a href="%1$s">login</a>!'), '../wp-login.php').'</p>';
624 echo '<table class="form-table">';
625 printf('<tr><th><label for="dbuser">%s</label></th><td><input type="text" name="dbuser" id="dbuser" /></td></tr>', __('DotClear Database User:'));
626 printf('<tr><th><label for="dbpass">%s</label></th><td><input type="password" name="dbpass" id="dbpass" /></td></tr>', __('DotClear Database Password:'));
627 printf('<tr><th><label for="dbname">%s</label></th><td><input type="text" name="dbname" id="dbname" /></td></tr>', __('DotClear Database Name:'));
628 printf('<tr><th><label for="dbhost">%s</label></th><td><input type="text" name="dbhost" id="dbhost" value="localhost" /></td></tr>', __('DotClear Database Host:'));
629 printf('<tr><th><label for="dbprefix">%s</label></th><td><input type="text" name="dbprefix" id="dbprefix" value="dc_"/></td></tr>', __('DotClear Table prefix:'));
630 printf('<tr><th><label for="dccharset">%s</label></th><td><input type="text" name="dccharset" id="dccharset" value="ISO-8859-15"/></td></tr>', __('Originating character set:'));
637 if (empty ($_GET['step']))
640 $step = (int) $_GET['step'];
645 check_admin_referer('import-dotclear');
649 if(get_option('dcuser'))
650 delete_option('dcuser');
651 add_option('dcuser', sanitize_user($_POST['dbuser'], true));
655 if(get_option('dcpass'))
656 delete_option('dcpass');
657 add_option('dcpass', sanitize_user($_POST['dbpass'], true));
662 if(get_option('dcname'))
663 delete_option('dcname');
664 add_option('dcname', sanitize_user($_POST['dbname'], true));
668 if(get_option('dchost'))
669 delete_option('dchost');
670 add_option('dchost', sanitize_user($_POST['dbhost'], true));
672 if($_POST['dccharset'])
674 if(get_option('dccharset'))
675 delete_option('dccharset');
676 add_option('dccharset', sanitize_user($_POST['dccharset'], true));
678 if($_POST['dbprefix'])
680 if(get_option('dcdbprefix'))
681 delete_option('dcdbprefix');
682 add_option('dcdbprefix', sanitize_user($_POST['dbprefix'], true));
695 $this->import_categories();
698 $this->import_users();
701 $result = $this->import_posts();
702 if ( is_wp_error( $result ) )
703 echo $result->get_error_message();
706 $this->import_comments();
709 $this->import_links();
712 $this->cleanup_dcimport();
719 function Dotclear_Import()
725 $dc_import = new Dotclear_Import();
727 register_importer('dotclear', __('DotClear'), __('Import categories, users, posts, comments, and links from a DotClear blog.'), array ($dc_import, 'dispatch'));