'mysql', 'db_host' => '', 'db_name' => '', 'db_user' => '', 'db_pwd' => '', 'db_prefix' => 'dc_', 'post_limit' => 20, 'cat_ids' => array() ); protected function setInfo() { $this->type = 'import'; $this->name = __('Dotclear 1.2 import'); $this->description = __('Import a Dotclear 1.2 installation into your current blog.'); } public function init() { $this->con =& $this->core->con; $this->prefix = $this->core->prefix; $this->blog_id = $this->core->blog->id; if (!isset($_SESSION['dc1_import_vars'])) { $_SESSION['dc1_import_vars'] = $this->base_vars; } $this->vars =& $_SESSION['dc1_import_vars']; if ($this->vars['post_limit'] > 0) { $this->post_limit = $this->vars['post_limit']; } } public function resetVars() { $this->vars = $this->base_vars;; unset($_SESSION['dc1_import_vars']); } public function process($do) { $this->action = $do; } # We handle process in another way to always display something to # user protected function guiprocess($do) { switch ($do) { case 'step1': $this->vars['db_driver'] = $_POST['db_driver']; $this->vars['db_host'] = $_POST['db_host']; $this->vars['db_name'] = $_POST['db_name']; $this->vars['db_user'] = $_POST['db_user']; $this->vars['db_pwd'] = $_POST['db_pwd']; $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; $this->vars['db_prefix'] = $_POST['db_prefix']; $db = $this->db(); $db->close(); $this->step = 2; echo $this->progressBar(1); break; case 'step2': $this->step = 2; $this->importUsers(); $this->step = 3; echo $this->progressBar(3); break; case 'step3': $this->step = 3; $this->importCategories(); if ($this->core->plugins->moduleExists('blogroll')) { $this->step = 4; echo $this->progressBar(5); } else { $this->step = 5; echo $this->progressBar(7); } break; case 'step4': $this->step = 4; $this->importLinks(); $this->step = 5; echo $this->progressBar(7); break; case 'step5': $this->step = 5; $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; if ($this->importPosts($percent) === -1) { http::redirect($this->getURL().'&do=ok'); } else { echo $this->progressBar(ceil($percent*0.93)+7); } break; case 'ok': $this->resetVars(); $this->core->blog->triggerBlog(); $this->step = 6; echo $this->progressBar(100); break; } } public function gui() { try { $this->guiprocess($this->action); } catch (Exception $e) { $this->error($e); } # db drivers $db_drivers = array( 'mysql' => 'mysql', 'mysqli' => 'mysqli' ); switch ($this->step) { case 1: echo '

'.sprintf(__('Import the content of a Dotclear 1.2\'s blog in the current blog: %s.'), ''.html::escapeHTML($this->core->blog->name).'').'

'. '

'.__('Please note that this process '. 'will empty your categories, blogroll, entries and comments on the current blog.').'

'; printf($this->imForm(1,__('General information'),__('Import my blog now')), '

'.__('We first need some information about your old Dotclear 1.2 installation.').'

'. '

'. form::combo('db_driver',$db_drivers,html::escapeHTML($this->vars['db_driver'])).'

'. '

'. form::field('db_host',30,255,html::escapeHTML($this->vars['db_host'])).'

'. '

'. form::field('db_name',30,255,html::escapeHTML($this->vars['db_name'])).'

'. '

'. form::field('db_user',30,255,html::escapeHTML($this->vars['db_user'])).'

'. '

'. form::password('db_pwd',30,255).'

'. '

'. form::field('db_prefix',30,255,html::escapeHTML($this->vars['db_prefix'])).'

'. '

'.__('Entries import options').'

'. '

'. form::field('post_limit',3,3,html::escapeHTML($this->vars['post_limit'])).'

' ); break; case 2: printf($this->imForm(2,__('Importing users')), $this->autoSubmit() ); break; case 3: printf($this->imForm(3,__('Importing categories')), $this->autoSubmit() ); break; case 4: printf($this->imForm(4,__('Importing blogroll')), $this->autoSubmit() ); break; case 5: $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); printf($this->imForm(5,$t), form::hidden(array('offset'),$this->post_offset). $this->autoSubmit() ); break; case 6: echo '

'.__('Please read carefully').'

'. ''. $this->congratMessage(); break; } } # Simple form for step by step process protected function imForm($step,$legend,$submit_value=null) { if (!$submit_value) { $submit_value = __('next step').' >'; } return '
'. '

'.$legend.'

'. '
'.$this->core->formNonce(). form::hidden(array('do'),'step'.$step). '%s'.'
'. '

'. '

'.__('Depending on the size of your blog, it could take a few minutes.').'

'. '
'; } # Error display protected function error($e) { echo '
'.__('Errors:').''. '

'.$e->getMessage().'

'; } # Database init protected function db() { $db = dbLayer::init($this->vars['db_driver'],$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); if ($rs->isEmpty()) { throw new Exception(__('Dotclear tables not found')); } while ($rs->fetch()) { $this->has_table[$rs->f(0)] = true; } # Set this to read data as they were written in Dotclear 1 try { $db->execute('SET NAMES DEFAULT'); } catch (Exception $e) {} $db->execute('SET CHARACTER SET DEFAULT'); $db->execute("SET COLLATION_CONNECTION = DEFAULT"); $db->execute("SET COLLATION_SERVER = DEFAULT"); $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); $this->post_count = $db->select( 'SELECT COUNT(post_id) FROM '.$this->vars['db_prefix'].'post ' )->f(0); return $db; } protected function cleanStr($str) { return text::cleanUTF8(@text::toUTF8($str)); } # Users import protected function importUsers() { $db = $this->db(); $prefix = $this->vars['db_prefix']; $rs = $db->select('SELECT * FROM '.$prefix.'user'); try { $this->con->begin(); while ($rs->fetch()) { if (!$this->core->userExists($rs->user_id)) { $cur = $this->con->openCursor($this->prefix.'user'); $cur->user_id = $rs->user_id; $cur->user_name = $rs->user_nom; $cur->user_firstname = $rs->user_prenom; $cur->user_displayname = $rs->user_pseudo; $cur->user_pwd = crypt::createPassword(); $cur->user_email = $rs->user_email; $cur->user_lang = $rs->user_lang; $cur->user_tz = $this->core->blog->settings->system->blog_timezone; $cur->user_post_status = $rs->user_post_pub ? 1 : -2; $cur->user_options = new ArrayObject(array( 'edit_size' => (integer) $rs->user_edit_size, 'post_format' => $rs->user_post_format )); $permissions = array(); switch ($rs->user_level) { case '0': $cur->user_status = 0; break; case '1': # editor $permissions['usage'] = true; break; case '5': # advanced editor $permissions['contentadmin'] = true; $permissions['categories'] = true; $permissions['media_admin'] = true; break; case '9': # admin $permissions['admin'] = true; break; } $this->core->addUser($cur); $this->core->setUserBlogPermissions( $rs->user_id, $this->blog_id, $permissions ); } } $this->con->commit(); $db->close(); } catch (Exception $e) { $this->con->rollback(); $db->close(); throw $e; } } # Categories import protected function importCategories() { $db = $this->db(); $prefix = $this->vars['db_prefix']; $rs = $db->select('SELECT * FROM '.$prefix.'categorie ORDER BY cat_ord ASC'); try { $this->con->execute( 'DELETE FROM '.$this->prefix.'category '. "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " ); $ord = 2; while ($rs->fetch()) { $cur = $this->con->openCursor($this->prefix.'category'); $cur->blog_id = $this->blog_id; $cur->cat_title = $this->cleanStr(htmlspecialchars_decode($rs->cat_libelle)); $cur->cat_desc = $this->cleanStr($rs->cat_desc); $cur->cat_url = $this->cleanStr($rs->cat_libelle_url); $cur->cat_lft = $ord++; $cur->cat_rgt = $ord++; $cur->cat_id = $this->con->select( 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' )->f(0) + 1; $this->vars['cat_ids'][$rs->cat_id] = $cur->cat_id; $cur->insert(); } $db->close(); } catch (Exception $e) { $db->close(); throw $e; } } # Blogroll import protected function importLinks() { $db = $this->db(); $prefix = $this->vars['db_prefix']; $rs = $db->select('SELECT * FROM '.$prefix.'link ORDER BY link_id ASC'); try { $this->con->execute( 'DELETE FROM '.$this->prefix.'link '. "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " ); while ($rs->fetch()) { $cur = $this->con->openCursor($this->prefix.'link'); $cur->blog_id = $this->blog_id; $cur->link_href = $this->cleanStr($rs->href); $cur->link_title = $this->cleanStr($rs->label); $cur->link_desc = $this->cleanStr($rs->title); $cur->link_lang = $this->cleanStr($rs->lang); $cur->link_xfn = $this->cleanStr($rs->rel); $cur->link_position = (integer) $rs->position; $cur->link_id = $this->con->select( 'SELECT MAX(link_id) FROM '.$this->prefix.'link' )->f(0) + 1; $cur->insert(); } $db->close(); } catch (Exception $e) { $db->close(); throw $e; } } # Entries import protected function importPosts(&$percent) { $db = $this->db(); $prefix = $this->vars['db_prefix']; $count = $db->select('SELECT COUNT(post_id) FROM '.$prefix.'post')->f(0); $rs = $db->select( 'SELECT * FROM '.$prefix.'post ORDER BY post_id ASC '. $db->limit($this->post_offset,$this->post_limit) ); try { if ($this->post_offset == 0) { $this->con->execute( 'DELETE FROM '.$this->prefix.'post '. "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " ); } while ($rs->fetch()) { $this->importPost($rs,$db); } $db->close(); } catch (Exception $e) { $db->close(); throw $e; } if ($rs->count() < $this->post_limit) { return -1; } else { $this->post_offset += $this->post_limit; } if ($this->post_offset > $this->post_count) { $percent = 100; } else { $percent = $this->post_offset * 100 / $this->post_count; } } protected function importPost($rs,$db) { $cur = $this->con->openCursor($this->prefix.'post'); $cur->blog_id = $this->blog_id; $cur->user_id = $rs->user_id; $cur->cat_id = (integer) $this->vars['cat_ids'][$rs->cat_id]; $cur->post_dt = $rs->post_dt; $cur->post_creadt = $rs->post_creadt; $cur->post_upddt = $rs->post_upddt; $cur->post_title = html::decodeEntities($this->cleanStr($rs->post_titre)); $cur->post_url = date('Y/m/d/',strtotime($cur->post_dt)).$rs->post_id.'-'.$rs->post_titre_url; $cur->post_url = substr($cur->post_url,0,191); $cur->post_format = $rs->post_content_wiki == '' ? 'xhtml' : 'wiki'; $cur->post_content_xhtml = $this->cleanStr($rs->post_content); $cur->post_excerpt_xhtml = $this->cleanStr($rs->post_chapo); if ($cur->post_format == 'wiki') { $cur->post_content = $this->cleanStr($rs->post_content_wiki); $cur->post_excerpt = $this->cleanStr($rs->post_chapo_wiki); } else { $cur->post_content = $this->cleanStr($rs->post_content); $cur->post_excerpt = $this->cleanStr($rs->post_chapo); } $cur->post_notes = $this->cleanStr($rs->post_notes); $cur->post_status = (integer) $rs->post_pub; $cur->post_selected = (integer) $rs->post_selected; $cur->post_open_comment = (integer) $rs->post_open_comment; $cur->post_open_tb = (integer) $rs->post_open_tb; $cur->post_lang = $rs->post_lang; $cur->post_words = implode(' ',text::splitWords( $cur->post_title.' '. $cur->post_excerpt_xhtml.' '. $cur->post_content_xhtml )); $cur->post_id = $this->con->select( 'SELECT MAX(post_id) FROM '.$this->prefix.'post' )->f(0) + 1; $cur->insert(); $this->importComments($rs->post_id,$cur->post_id,$db); $this->importPings($rs->post_id,$cur->post_id,$db); # Load meta if we have some in DC1 if (isset($this->has_table[$this->vars['db_prefix'].'post_meta'])) { $this->importMeta($rs->post_id,$cur->post_id,$db); } } # Comments import protected function importComments($post_id,$new_post_id,$db) { $count_c = $count_t = 0; $rs = $db->select( 'SELECT * FROM '.$this->vars['db_prefix'].'comment '. 'WHERE post_id = '.(integer) $post_id.' ' ); while ($rs->fetch()) { $cur = $this->con->openCursor($this->prefix.'comment'); $cur->post_id = (integer) $new_post_id; $cur->comment_author = $this->cleanStr($rs->comment_auteur); $cur->comment_status = (integer) $rs->comment_pub; $cur->comment_dt = $rs->comment_dt; $cur->comment_upddt = $rs->comment_upddt; $cur->comment_email = $this->cleanStr($rs->comment_email); $cur->comment_content = $this->cleanStr($rs->comment_content); $cur->comment_ip = $rs->comment_ip; $cur->comment_trackback = (integer) $rs->comment_trackback; $cur->comment_site = $this->cleanStr($rs->comment_site); if ($cur->comment_site != '' && !preg_match('!^http://.*$!',$cur->comment_site)) { $cur->comment_site = substr('http://'.$cur->comment_site,0,255); } if ($rs->exists('spam') && $rs->spam && $rs->comment_status = 0) { $cur->comment_status = -2; } $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); $cur->comment_id = $this->con->select( 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' )->f(0) + 1; $cur->insert(); if ($cur->comment_trackback && $cur->comment_status == 1) { $count_t++; } elseif ($cur->comment_status == 1) { $count_c++; } } if ($count_t > 0 || $count_c > 0) { $this->con->execute( 'UPDATE '.$this->prefix.'post SET '. 'nb_comment = '.$count_c.', '. 'nb_trackback = '.$count_t.' '. 'WHERE post_id = '.(integer) $new_post_id.' ' ); } } # Pings import protected function importPings($post_id,$new_post_id,$db) { $urls = array(); $rs = $db->select( 'SELECT * FROM '.$this->vars['db_prefix'].'ping '. 'WHERE post_id = '.(integer) $post_id ); while ($rs->fetch()) { $url = $this->cleanStr($rs->ping_url); if (isset($urls[$url])) { continue; } $cur = $this->con->openCursor($this->prefix.'ping'); $cur->post_id = (integer) $new_post_id; $cur->ping_url = $url; $cur->ping_dt = $rs->ping_dt; $cur->insert(); $urls[$url] = true; } } # Meta import protected function importMeta($post_id,$new_post_id,$db) { $rs = $db->select( 'SELECT * FROM '.$this->vars['db_prefix'].'post_meta '. 'WHERE post_id = '.(integer) $post_id.' ' ); if ($rs->isEmpty()) { return; } while ($rs->fetch()) { $this->core->meta->setPostMeta($new_post_id,$this->cleanStr($rs->meta_key),$this->cleanStr($rs->meta_value)); } } }