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));
417 'comment_post_ID' => $comment_post_ID,
418 'comment_author' => $name,
419 'comment_author_email' => $email,
420 'comment_author_url' => $web,
421 'comment_author_IP' => $comment_ip,
422 'comment_date' => $comment_dt,
423 'comment_date_gmt' => $comment_dt,
424 'comment_content' => $message,
425 'comment_approved' => $comment_approved);
426 $comment = wp_filter_comment($comment);
428 if ( $cinfo = comment_exists($name, $comment_dt) ) {
430 $comment['comment_ID'] = $cinfo;
431 $ret_id = wp_update_comment($comment);
434 $ret_id = wp_insert_comment($comment);
436 $dccm2wpcm[$comment_ID] = $ret_id;
438 // Store Comment ID translation for future use
439 add_option('dccm2wpcm', $dccm2wpcm);
441 // Associate newly formed categories with posts
442 get_comment_count($ret_id);
445 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
448 echo __('No Comments to Import!');
452 function links2wp($links='')
454 // General Housekeeping
458 // Deal with the links
461 echo '<p>'.__('Importing Links...').'<br /><br /></p>';
462 foreach($links as $link)
468 if ($cinfo = is_term(csc ($title), 'link_category')) {
469 $category = $cinfo['term_id'];
471 $category = wp_insert_term($wpdb->escape (csc ($title)), 'link_category');
472 $category = $category['term_id'];
475 $linkname = $wpdb->escape(csc ($label));
476 $description = $wpdb->escape(csc ($title));
478 if($linfo = link_exists($linkname)) {
479 $ret_id = wp_insert_link(array(
482 'link_name' => $linkname,
483 'link_category' => $category,
484 'link_description' => $description)
487 $ret_id = wp_insert_link(array(
489 'link_name' => $linkname,
490 'link_category' => $category,
491 'link_description' => $description)
494 $dclinks2wplinks[$link_id] = $ret_id;
497 add_option('dclinks2wplinks',$dclinks2wplinks);
499 printf(_n('Done! <strong>%s</strong> link or link category imported.', 'Done! <strong>%s</strong> links or link categories imported.', $count), $count);
500 echo '<br /><br /></p>';
503 echo __('No Links to Import!');
507 function import_categories()
510 $cats = $this->get_dc_cats();
511 $this->cat2wp($cats);
512 add_option('dc_cats', $cats);
516 echo '<form action="admin.php?import=dotclear&step=2" method="post">';
517 wp_nonce_field('import-dotclear');
518 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Users'));
523 function import_users()
526 $users = $this->get_dc_users();
527 $this->users2wp($users);
529 echo '<form action="admin.php?import=dotclear&step=3" method="post">';
530 wp_nonce_field('import-dotclear');
531 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Posts'));
535 function import_posts()
538 $posts = $this->get_dc_posts();
539 $result = $this->posts2wp($posts);
540 if ( is_wp_error( $result ) )
543 echo '<form action="admin.php?import=dotclear&step=4" method="post">';
544 wp_nonce_field('import-dotclear');
545 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Comments'));
549 function import_comments()
552 $comments = $this->get_dc_comments();
553 $this->comments2wp($comments);
555 echo '<form action="admin.php?import=dotclear&step=5" method="post">';
556 wp_nonce_field('import-dotclear');
557 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Import Links'));
561 function import_links()
564 $links = $this->get_dc_links();
565 $this->links2wp($links);
566 add_option('dc_links', $links);
568 echo '<form action="admin.php?import=dotclear&step=6" method="post">';
569 wp_nonce_field('import-dotclear');
570 printf('<p class="submit"><input type="submit" name="submit" class="button" value="%s" /></p>', esc_attr__('Finish'));
574 function cleanup_dcimport()
576 delete_option('dcdbprefix');
577 delete_option('dc_cats');
578 delete_option('dcid2wpid');
579 delete_option('dccat2wpcat');
580 delete_option('dcposts2wpposts');
581 delete_option('dccm2wpcm');
582 delete_option('dclinks2wplinks');
583 delete_option('dcuser');
584 delete_option('dcpass');
585 delete_option('dcname');
586 delete_option('dchost');
587 delete_option('dccharset');
588 do_action('import_done', 'dotclear');
594 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>';
595 echo '<h3>'.__('Users').'</h3>';
596 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">Log in</a> and change it.'), '/wp-login.php').'</p>';
597 echo '<h3>'.__('Preserving Authors').'</h3>';
598 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>';
599 echo '<h3>'.__('Textile').'</h3>';
600 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>';
601 echo '<h3>'.__('WordPress Resources').'</h3>';
602 echo '<p>'.__('Finally, there are numerous WordPress resources around the internet. Some of them are:').'</p>';
604 echo '<li>'.__('<a href="http://www.wordpress.org">The official WordPress site</a>').'</li>';
605 echo '<li>'.__('<a href="http://wordpress.org/support/">The WordPress support forums</a>').'</li>';
606 echo '<li>'.__('<a href="http://codex.wordpress.org">The Codex (In other words, the WordPress Bible)</a>').'</li>';
608 echo '<p>'.sprintf(__('That’s it! What are you waiting for? Go <a href="%1$s">log in</a>!'), '../wp-login.php').'</p>';
613 echo '<table class="form-table">';
614 printf('<tr><th><label for="dbuser">%s</label></th><td><input type="text" name="dbuser" id="dbuser" /></td></tr>', __('DotClear Database User:'));
615 printf('<tr><th><label for="dbpass">%s</label></th><td><input type="password" name="dbpass" id="dbpass" /></td></tr>', __('DotClear Database Password:'));
616 printf('<tr><th><label for="dbname">%s</label></th><td><input type="text" name="dbname" id="dbname" /></td></tr>', __('DotClear Database Name:'));
617 printf('<tr><th><label for="dbhost">%s</label></th><td><input type="text" name="dbhost" id="dbhost" value="localhost" /></td></tr>', __('DotClear Database Host:'));
618 printf('<tr><th><label for="dbprefix">%s</label></th><td><input type="text" name="dbprefix" id="dbprefix" value="dc_"/></td></tr>', __('DotClear Table prefix:'));
619 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:'));
626 if (empty ($_GET['step']))
629 $step = (int) $_GET['step'];
634 check_admin_referer('import-dotclear');
638 if(get_option('dcuser'))
639 delete_option('dcuser');
640 add_option('dcuser', sanitize_user($_POST['dbuser'], true));
644 if(get_option('dcpass'))
645 delete_option('dcpass');
646 add_option('dcpass', sanitize_user($_POST['dbpass'], true));
651 if(get_option('dcname'))
652 delete_option('dcname');
653 add_option('dcname', sanitize_user($_POST['dbname'], true));
657 if(get_option('dchost'))
658 delete_option('dchost');
659 add_option('dchost', sanitize_user($_POST['dbhost'], true));
661 if($_POST['dccharset'])
663 if(get_option('dccharset'))
664 delete_option('dccharset');
665 add_option('dccharset', sanitize_user($_POST['dccharset'], true));
667 if($_POST['dbprefix'])
669 if(get_option('dcdbprefix'))
670 delete_option('dcdbprefix');
671 add_option('dcdbprefix', sanitize_user($_POST['dbprefix'], true));
684 $this->import_categories();
687 $this->import_users();
690 $result = $this->import_posts();
691 if ( is_wp_error( $result ) )
692 echo $result->get_error_message();
695 $this->import_comments();
698 $this->import_links();
701 $this->cleanup_dcimport();
708 function Dotclear_Import()
714 $dc_import = new Dotclear_Import();
716 register_importer('dotclear', __('DotClear'), __('Import categories, users, posts, comments, and links from a DotClear blog.'), array ($dc_import, 'dispatch'));