3 Add These Functions to make our lives easier
5 if(!function_exists('get_catbynicename'))
7 function get_catbynicename($category_nicename)
11 $cat_id -= 0; // force numeric
12 $name = $wpdb->get_var('SELECT cat_ID FROM '.$wpdb->categories.' WHERE category_nicename="'.$category_nicename.'"');
18 if(!function_exists('get_comment_count'))
20 function get_comment_count($post_ID)
23 return $wpdb->get_var('SELECT count(*) FROM '.$wpdb->comments.' WHERE comment_post_ID = '.$post_ID);
27 if(!function_exists('link_cat_exists'))
29 function link_cat_exists($catname)
32 return $wpdb->get_var('SELECT cat_id FROM '.$wpdb->linkcategories.' WHERE cat_name = "'.$wpdb->escape($catname).'"');
36 if(!function_exists('link_exists'))
38 function link_exists($linkname)
41 return $wpdb->get_var('SELECT link_id FROM '.$wpdb->links.' WHERE link_name = "'.$linkname.'"');
47 Taken from http://www.php.net/manual/fr/function.mb-detect-encoding.php#50087
50 // utf8 encoding validation developed based on Wikipedia entry at:
51 // http://en.wikipedia.org/wiki/UTF-8
53 // Implemented as a recursive descent parser based on a simple state machine
54 // copyright 2005 Maarten Meijer
56 // This cries out for a C-implementation to be included in PHP core
58 function valid_1byte($char) {
59 if(!is_int($char)) return false;
60 return ($char & 0x80) == 0x00;
63 function valid_2byte($char) {
64 if(!is_int($char)) return false;
65 return ($char & 0xE0) == 0xC0;
68 function valid_3byte($char) {
69 if(!is_int($char)) return false;
70 return ($char & 0xF0) == 0xE0;
73 function valid_4byte($char) {
74 if(!is_int($char)) return false;
75 return ($char & 0xF8) == 0xF0;
78 function valid_nextbyte($char) {
79 if(!is_int($char)) return false;
80 return ($char & 0xC0) == 0x80;
83 function valid_utf8($string) {
84 $len = strlen($string);
87 $char = ord(substr($string, $i++, 1));
88 if(valid_1byte($char)) { // continue
90 } else if(valid_2byte($char)) { // check 1 byte
91 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
93 } else if(valid_3byte($char)) { // check 2 bytes
94 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
96 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
98 } else if(valid_4byte($char)) { // check 3 bytes
99 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
101 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
103 if(!valid_nextbyte(ord(substr($string, $i++, 1))))
111 if (valid_utf8 ($s)) {
114 return iconv(get_option ("dccharset"),"UTF-8",$s);
118 function textconv ($s) {
119 return csc (preg_replace ('|(?<!<br />)\s*\n|', ' ', $s));
123 The Main Importer Class
125 class Dotclear_Import {
129 echo '<div class="wrap">';
130 echo '<h2>'.__('Import Dotclear').'</h2>';
131 echo '<p>'.__('Steps may take a few minutes depending on the size of your database. Please be patient.').'</p>';
141 echo '<p>'.__('Howdy! This importer allows you to extract posts from a Dotclear database into your blog. Mileage may vary.').'</p>';
142 echo '<p>'.__('Your Dotclear Configuration settings are as follows:').'</p>';
143 echo '<form action="admin.php?import=dotclear&step=1" method="post">';
145 echo '<input type="submit" name="submit" value="'.__('Import Categories').'" />';
149 function get_dc_cats()
152 // General Housekeeping
153 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
154 set_magic_quotes_runtime(0);
155 $prefix = get_option('tpre');
158 return $dcdb->get_results('SELECT * FROM dc_categorie', ARRAY_A);
161 function get_dc_users()
164 // General Housekeeping
165 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
166 set_magic_quotes_runtime(0);
167 $prefix = get_option('tpre');
171 return $dcdb->get_results('SELECT * FROM dc_user', ARRAY_A);
174 function get_dc_posts()
176 // General Housekeeping
177 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
178 set_magic_quotes_runtime(0);
179 $prefix = get_option('tpre');
182 return $dcdb->get_results('SELECT dc_post.*, dc_categorie.cat_libelle_url AS post_cat_name
183 FROM dc_post INNER JOIN dc_categorie
184 ON dc_post.cat_id = dc_categorie.cat_id', ARRAY_A);
187 function get_dc_comments()
190 // General Housekeeping
191 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
192 set_magic_quotes_runtime(0);
193 $prefix = get_option('tpre');
196 return $dcdb->get_results('SELECT * FROM dc_comment', ARRAY_A);
199 function get_dc_links()
201 //General Housekeeping
202 $dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
203 set_magic_quotes_runtime(0);
204 $prefix = get_option('tpre');
206 return $dcdb->get_results('SELECT * FROM dc_link ORDER BY position', ARRAY_A);
209 function cat2wp($categories='')
211 // General Housekeeping
214 $dccat2wpcat = array();
216 if(is_array($categories))
218 echo '<p>'.__('Importing Categories...').'<br /><br /></p>';
219 foreach ($categories as $category)
224 // Make Nice Variables
225 $name = $wpdb->escape($cat_libelle_url);
226 $title = $wpdb->escape(csc ($cat_libelle));
227 $desc = $wpdb->escape(csc ($cat_desc));
229 if($cinfo = category_exists($name))
231 $ret_id = wp_insert_category(array('cat_ID' => $cinfo, 'category_nicename' => $name, 'cat_name' => $title, 'category_description' => $desc));
235 $ret_id = wp_insert_category(array('category_nicename' => $name, 'cat_name' => $title, 'category_description' => $desc));
237 $dccat2wpcat[$id] = $ret_id;
240 // Store category translation for future use
241 add_option('dccat2wpcat',$dccat2wpcat);
242 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> categories imported.'), $count).'<br /><br /></p>';
245 echo __('No Categories to Import!');
249 function users2wp($users='')
251 // General Housekeeping
254 $dcid2wpid = array();
259 echo '<p>'.__('Importing Users...').'<br /><br /></p>';
260 foreach($users as $user)
265 // Make Nice Variables
266 $name = $wpdb->escape(csc ($name));
267 $RealName = $wpdb->escape(csc ($user_pseudo));
269 if($uinfo = get_userdatabylogin($name))
272 $ret_id = wp_insert_user(array(
274 'user_login' => $user_id,
275 'user_nicename' => $Realname,
276 'user_email' => $user_email,
277 'user_url' => 'http://',
278 'display_name' => $Realname)
283 $ret_id = wp_insert_user(array(
284 'user_login' => $user_id,
285 'user_nicename' => csc ($user_pseudo),
286 'user_email' => $user_email,
287 'user_url' => 'http://',
288 'display_name' => $Realname)
291 $dcid2wpid[$user_id] = $ret_id;
293 // Set Dotclear-to-WordPress permissions translation
295 // Update Usermeta Data
296 $user = new WP_User($ret_id);
297 $wp_perms = $user_level + 1;
298 if(10 == $wp_perms) { $user->set_role('administrator'); }
299 else if(9 == $wp_perms) { $user->set_role('editor'); }
300 else if(5 <= $wp_perms) { $user->set_role('editor'); }
301 else if(4 <= $wp_perms) { $user->set_role('author'); }
302 else if(3 <= $wp_perms) { $user->set_role('contributor'); }
303 else if(2 <= $wp_perms) { $user->set_role('contributor'); }
304 else { $user->set_role('subscriber'); }
306 update_usermeta( $ret_id, 'wp_user_level', $wp_perms);
307 update_usermeta( $ret_id, 'rich_editing', 'false');
308 update_usermeta( $ret_id, 'first_name', csc ($user_prenom));
309 update_usermeta( $ret_id, 'last_name', csc ($user_nom));
310 }// End foreach($users as $user)
312 // Store id translation array for future use
313 add_option('dcid2wpid',$dcid2wpid);
316 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> users imported.'), $count).'<br /><br /></p>';
318 }// End if(is_array($users)
320 echo __('No Users to Import!');
323 }// End function user2wp()
325 function posts2wp($posts='')
327 // General Housekeeping
330 $dcposts2wpposts = array();
336 echo '<p>'.__('Importing Posts...').'<br /><br /></p>';
337 foreach($posts as $post)
342 // Set Dotclear-to-WordPress status translation
343 $stattrans = array(0 => 'draft', 1 => 'publish');
344 $comment_status_map = array (0 => 'closed', 1 => 'open');
346 //Can we do this more efficiently?
347 $uinfo = ( get_userdatabylogin( $user_id ) ) ? get_userdatabylogin( $user_id ) : 1;
348 $authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
350 $Title = $wpdb->escape(csc ($post_titre));
351 $post_content = textconv ($post_content);
352 if ($post_chapo != "") {
353 $post_excerpt = textconv ($post_chapo);
354 $post_content = $post_excerpt ."\n<!--more-->\n".$post_content;
356 $post_excerpt = $wpdb->escape ($post_excerpt);
357 $post_content = $wpdb->escape ($post_content);
358 $post_status = $stattrans[$post_pub];
360 // Import Post data into WordPress
362 if($pinfo = post_exists($Title,$post_content))
364 $ret_id = wp_insert_post(array(
366 'post_author' => $authorid,
367 'post_date' => $post_dt,
368 'post_date_gmt' => $post_dt,
369 'post_modified' => $post_upddt,
370 'post_modified_gmt' => $post_upddt,
371 'post_title' => $Title,
372 'post_content' => $post_content,
373 'post_excerpt' => $post_excerpt,
374 'post_status' => $post_status,
375 'post_name' => $post_titre_url,
376 'comment_status' => $comment_status_map[$post_open_comment],
377 'ping_status' => $comment_status_map[$post_open_tb],
378 'comment_count' => $post_nb_comment + $post_nb_trackback)
383 $ret_id = wp_insert_post(array(
384 'post_author' => $authorid,
385 'post_date' => $post_dt,
386 'post_date_gmt' => $post_dt,
387 'post_modified' => $post_modified_gmt,
388 'post_modified_gmt' => $post_modified_gmt,
389 'post_title' => $Title,
390 'post_content' => $post_content,
391 'post_excerpt' => $post_excerpt,
392 'post_status' => $post_status,
393 'post_name' => $post_titre_url,
394 'comment_status' => $comment_status_map[$post_open_comment],
395 'ping_status' => $comment_status_map[$post_open_tb],
396 'comment_count' => $post_nb_comment + $post_nb_trackback)
399 $dcposts2wpposts[$post_id] = $ret_id;
401 // Make Post-to-Category associations
403 if($cat1 = get_catbynicename($post_cat_name)) { $cats[1] = $cat1; }
405 if(!empty($cats)) { wp_set_post_cats('', $ret_id, $cats); }
408 // Store ID translation for later use
409 add_option('dcposts2wpposts',$dcposts2wpposts);
411 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> posts imported.'), $count).'<br /><br /></p>';
415 function comments2wp($comments='')
417 // General Housekeeping
420 $dccm2wpcm = array();
421 $postarr = get_option('dcposts2wpposts');
424 if(is_array($comments))
426 echo '<p>'.__('Importing Comments...').'<br /><br /></p>';
427 foreach($comments as $comment)
433 $comment_ID = ltrim($comment_id, '0');
434 $comment_post_ID = $postarr[$post_id];
435 $comment_approved = "$comment_pub";
436 $name = $wpdb->escape(csc ($comment_auteur));
437 $email = $wpdb->escape($comment_email);
438 $web = "http://".$wpdb->escape($comment_site);
439 $message = $wpdb->escape(textconv ($comment_content));
441 if($cinfo = comment_exists($name, $comment_dt))
444 $ret_id = wp_update_comment(array(
445 'comment_ID' => $cinfo,
446 'comment_post_ID' => $comment_post_ID,
447 'comment_author' => $name,
448 'comment_author_email' => $email,
449 'comment_author_url' => $web,
450 'comment_author_IP' => $comment_ip,
451 'comment_date' => $comment_dt,
452 'comment_date_gmt' => $comment_dt,
453 'comment_content' => $message,
454 'comment_approved' => $comment_approved)
460 $ret_id = wp_insert_comment(array(
461 'comment_post_ID' => $comment_post_ID,
462 'comment_author' => $name,
463 'comment_author_email' => $email,
464 'comment_author_url' => $web,
465 'comment_author_IP' => $comment_ip,
466 'comment_date' => $comment_dt,
467 'comment_date_gmt' => $comment_dt,
468 'comment_content' => $message,
469 'comment_approved' => $comment_approved)
472 $dccm2wpcm[$comment_ID] = $ret_id;
474 // Store Comment ID translation for future use
475 add_option('dccm2wpcm', $dccm2wpcm);
477 // Associate newly formed categories with posts
478 get_comment_count($ret_id);
481 echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
484 echo __('No Comments to Import!');
488 function links2wp($links='')
490 // General Housekeeping
494 // Deal with the links
497 echo '<p>'.__('Importing Links...').'<br /><br /></p>';
498 foreach($links as $link)
504 if ($cinfo = link_cat_exists (csc ($title))) {
507 $wpdb->query ("INSERT INTO $wpdb->linkcategories (cat_name) VALUES ('".
508 $wpdb->escape (csc ($title))."')");
509 $category = $wpdb->insert_id;
512 $linkname = $wpdb->escape(csc ($label));
513 $description = $wpdb->escape(csc ($title));
515 if($linfo = link_exists($linkname)) {
516 $ret_id = wp_insert_link(array(
519 'link_name' => $linkname,
520 'link_category' => $category,
521 'link_description' => $description)
524 $ret_id = wp_insert_link(array(
526 'link_name' => $linkname,
527 'link_category' => $category,
528 'link_description' => $description)
531 $dclinks2wplinks[$link_id] = $ret_id;
534 add_option('dclinks2wplinks',$dclinks2wplinks);
536 printf(__('Done! <strong>%s</strong> links or link categories imported'), $count);
537 echo '<br /><br /></p>';
540 echo __('No Links to Import!');
544 function import_categories()
547 $cats = $this->get_dc_cats();
548 $this->cat2wp($cats);
549 add_option('dc_cats', $cats);
553 echo '<form action="admin.php?import=dotclear&step=2" method="post">';
554 printf('<input type="submit" name="submit" value="%s" />', __('Import Users'));
559 function import_users()
562 $users = $this->get_dc_users();
563 $this->users2wp($users);
565 echo '<form action="admin.php?import=dotclear&step=3" method="post">';
566 printf('<input type="submit" name="submit" value="%s" />', __('Import Posts'));
570 function import_posts()
573 $posts = $this->get_dc_posts();
574 $this->posts2wp($posts);
576 echo '<form action="admin.php?import=dotclear&step=4" method="post">';
577 printf('<input type="submit" name="submit" value="%s" />', __('Import Comments'));
581 function import_comments()
584 $comments = $this->get_dc_comments();
585 $this->comments2wp($comments);
587 echo '<form action="admin.php?import=dotclear&step=5" method="post">';
588 printf('<input type="submit" name="submit" value="%s" />', __('Import Links'));
592 function import_links()
595 $links = $this->get_dc_links();
596 $this->links2wp($links);
597 add_option('dc_links', $links);
599 echo '<form action="admin.php?import=dotclear&step=6" method="post">';
600 printf('<input type="submit" name="submit" value="%s" />', __('Finish'));
604 function cleanup_dcimport()
606 delete_option('tpre');
607 delete_option('dc_cats');
608 delete_option('dcid2wpid');
609 delete_option('dccat2wpcat');
610 delete_option('dcposts2wpposts');
611 delete_option('dccm2wpcm');
612 delete_option('dclinks2wplinks');
613 delete_option('dcuser');
614 delete_option('dcpass');
615 delete_option('dcname');
616 delete_option('dchost');
617 delete_option('dccharset');
623 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>';
624 echo '<h3>'.__('Users').'</h3>';
625 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>';
626 echo '<h3>'.__('Preserving Authors').'</h3>';
627 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>';
628 echo '<h3>'.__('Textile').'</h3>';
629 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/2004/04/19/wordpress-plugin-textile-20/">Textile for WordPress</a>. Trust me... You\'ll want it.').'</p>';
630 echo '<h3>'.__('WordPress Resources').'</h3>';
631 echo '<p>'.__('Finally, there are numerous WordPress resources around the internet. Some of them are:').'</p>';
633 echo '<li>'.__('<a href="http://www.wordpress.org">The official WordPress site</a>').'</li>';
634 echo '<li>'.__('<a href="http://wordpress.org/support/">The WordPress support forums').'</li>';
635 echo '<li>'.__('<a href="http://codex.wordpress.org">The Codex (In other words, the WordPress Bible)</a>').'</li>';
637 echo '<p>'.sprintf(__('That\'s it! What are you waiting for? Go <a href="%1$s">login</a>!'), '/wp-login.php').'</p>';
643 printf('<li><label for="dbuser">%s</label> <input type="text" name="dbuser" id="dbuser" /></li>', __('Dotclear Database User:'));
644 printf('<li><label for="dbpass">%s</label> <input type="password" name="dbpass" id="dbpass" /></li>', __('Dotclear Database Password:'));
645 printf('<li><label for="dbname">%s</label> <input type="text" name="dbname" id="dbname" /></li>', __('Dotclear Database Name:'));
646 printf('<li><label for="dbhost">%s</label> <input type="text" name="dbhost" id="dbhost" value="localhost" /></li>', __('Dotclear Database Host:'));
647 /* printf('<li><label for="dbprefix">%s</label> <input type="text" name="dbprefix" /></li>', __('Dotclear Table prefix (if any):')); */
648 printf('<li><label for="dccharset">%s</label> <input type="text" id="dccharset" name="dccharset" value="ISO-8859-15"/></li>', __('Originating character set:'));
655 if (empty ($_GET['step']))
658 $step = (int) $_GET['step'];
665 if(get_option('dcuser'))
666 delete_option('dcuser');
667 add_option('dcuser',$_POST['dbuser']);
671 if(get_option('dcpass'))
672 delete_option('dcpass');
673 add_option('dcpass',$_POST['dbpass']);
678 if(get_option('dcname'))
679 delete_option('dcname');
680 add_option('dcname',$_POST['dbname']);
684 if(get_option('dchost'))
685 delete_option('dchost');
686 add_option('dchost',$_POST['dbhost']);
688 if($_POST['dccharset'])
690 if(get_option('dccharset'))
691 delete_option('dccharset');
692 add_option('dccharset',$_POST['dccharset']);
694 if($_POST['dbprefix'])
696 if(get_option('tpre'))
697 delete_option('tpre');
698 add_option('tpre',$_POST['dbprefix']);
711 $this->import_categories();
714 $this->import_users();
717 $this->import_posts();
720 $this->import_comments();
723 $this->import_links();
726 $this->cleanup_dcimport();
733 function Dotclear_Import()
739 $dc_import = new Dotclear_Import();
740 register_importer('dotclear', 'Dotclear', __('Import posts from a Dotclear Blog'), array ($dc_import, 'dispatch'));