- Timestamp:
- 03/02/18 15:55:06 (8 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/importExport/inc/class.dc.import.wp.php
r3606 r3725 10 10 # 11 11 # -- END LICENSE BLOCK ----------------------------------------- 12 if (!defined('DC_RC_PATH')) { return;}12 if (!defined('DC_RC_PATH')) {return;} 13 13 14 14 class dcImportWP extends dcIeModule 15 15 { 16 protected $con; 17 protected $prefix; 18 protected $blog_id; 19 20 protected $action = null; 21 protected $step = 1; 22 23 protected $post_offset = 0; 24 protected $post_limit = 20; 25 protected $post_count = 0; 26 27 protected $has_table = array(); 28 29 protected $vars; 30 protected $base_vars = array( 31 'db_host' => '', 32 'db_name' => '', 33 'db_user' => '', 34 'db_pwd' => '', 35 'db_prefix' => 'wp_', 36 'ignore_first_cat' => 1, 37 'cat_import' => 1, 38 'cat_as_tags' => '', 39 'cat_tags_prefix' => 'cat: ', 40 'post_limit' => 20, 41 'post_formater' => 'xhtml', 42 'comment_formater' => 'xhtml', 43 'user_ids' => array(), 44 'cat_ids' => array(), 45 'permalink_template' => 'p=%post_id%', 46 'permalink_tags' => array( 47 '%year%', 48 '%monthnum%', 49 '%day%', 50 '%hour%', 51 '%minute%', 52 '%second%', 53 '%postname%', 54 '%post_id%', 55 '%category%', 56 '%author%' 57 ) 58 ); 59 protected $formaters; 60 61 protected function setInfo() 62 { 63 $this->type = 'import'; 64 $this->name = __('WordPress import'); 65 $this->description = __('Import a WordPress installation into your current blog.'); 66 } 67 68 public function init() 69 { 70 $this->con =& $this->core->con; 71 $this->prefix = $this->core->prefix; 72 $this->blog_id = $this->core->blog->id; 73 74 if (!isset($_SESSION['wp_import_vars'])) { 75 $_SESSION['wp_import_vars'] = $this->base_vars; 76 } 77 $this->vars =& $_SESSION['wp_import_vars']; 78 79 if ($this->vars['post_limit'] > 0) { 80 $this->post_limit = $this->vars['post_limit']; 81 } 82 83 $this->formaters = dcAdminCombos::getFormatersCombo(); 84 } 85 86 public function resetVars() 87 { 88 $this->vars = $this->base_vars;; 89 unset($_SESSION['wp_import_vars']); 90 } 91 92 public function process($do) 93 { 94 $this->action = $do; 95 } 96 97 # We handle process in another way to always display something to 98 # user 99 protected function guiprocess($do) 100 { 101 switch ($do) 102 { 103 case 'step1': 104 $this->vars['db_host'] = $_POST['db_host']; 105 $this->vars['db_name'] = $_POST['db_name']; 106 $this->vars['db_user'] = $_POST['db_user']; 107 $this->vars['db_pwd'] = $_POST['db_pwd']; 108 $this->vars['db_prefix'] = $_POST['db_prefix']; 109 $this->vars['ignore_first_cat'] = isset($_POST['ignore_first_cat']); 110 $this->vars['cat_import'] = isset($_POST['cat_import']); 111 $this->vars['cat_as_tags'] = isset($_POST['cat_as_tags']); 112 $this->vars['cat_tags_prefix'] = $_POST['cat_tags_prefix']; 113 $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; 114 $this->vars['post_formater'] = isset($this->formaters[$_POST['post_formater']]) ? $_POST['post_formater'] : 'xhtml'; 115 $this->vars['comment_formater'] = isset($this->formaters[$_POST['comment_formater']]) ? $_POST['comment_formater'] : 'xhtml'; 116 $db = $this->db(); 117 $db->close(); 118 $this->step = 2; 119 echo $this->progressBar(1); 120 break; 121 case 'step2': 122 $this->step = 2; 123 $this->importUsers(); 124 $this->step = 3; 125 echo $this->progressBar(3); 126 break; 127 case 'step3': 128 $this->step = 3; 129 $this->importCategories(); 130 if ($this->core->plugins->moduleExists('blogroll')) { 131 $this->step = 4; 132 echo $this->progressBar(5); 133 } else { 134 $this->step = 5; 135 echo $this->progressBar(7); 136 } 137 break; 138 case 'step4': 139 $this->step = 4; 140 $this->importLinks(); 141 $this->step = 5; 142 echo $this->progressBar(7); 143 break; 144 case 'step5': 145 $this->step = 5; 146 $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; 147 if ($this->importPosts($percent) === -1) { 148 http::redirect($this->getURL().'&do=ok'); 149 } else { 150 echo $this->progressBar(ceil($percent*0.93)+7); 151 } 152 break; 153 case 'ok': 154 $this->resetVars(); 155 $this->core->blog->triggerBlog(); 156 $this->step = 6; 157 echo $this->progressBar(100); 158 break; 159 } 160 } 161 162 public function gui() 163 { 164 try { 165 $this->guiprocess($this->action); 166 } catch (Exception $e) { 167 $this->error($e); 168 } 169 170 switch ($this->step) 171 { 172 case 1: 173 echo 174 '<p>'.sprintf(__('This will import your WordPress content as new content in the current blog: %s.'), 175 '<strong>'.html::escapeHTML($this->core->blog->name).'</strong>').'</p>'. 176 '<p class="warning">'.__('Please note that this process '. 177 'will empty your categories, blogroll, entries and comments on the current blog.').'</p>'; 178 179 printf($this->imForm(1,__('General information'),__('Import my blog now')), 180 '<p>'.__('We first need some information about your old WordPress installation.').'</p>'. 181 '<p><label for="db_host">'.__('Database Host Name:').'</label> '. 182 form::field('db_host',30,255,html::escapeHTML($this->vars['db_host'])).'</p>'. 183 '<p><label for="db_name">'.__('Database Name:',html::escapeHTML($this->vars['db_name'])).'</label> '. 184 form::field('db_name',30,255,html::escapeHTML($this->vars['db_name'])).'</p>'. 185 '<p><label for="db_user">'.__('Database User Name:').'</label> '. 186 form::field('db_user',30,255,html::escapeHTML($this->vars['db_user'])).'</p>'. 187 '<p><label for="db_pwd">'.__('Database Password:').'</label> '. 188 form::password('db_pwd',30,255).'</p>'. 189 '<p><label for="db_prefix">'.__('Database Tables Prefix:').'</label> '. 190 form::field('db_prefix',30,255,html::escapeHTML($this->vars['db_prefix'])).'</p>'. 191 192 '<h3 class="vertical-separator">'.__('Entries import options').'</h3>'. 193 '<div class="two-cols">'. 194 195 '<div class="col">'. 196 '<p>'.__('WordPress and Dotclear\'s handling of categories are quite different. '. 197 'You can assign several categories to a single post in WordPress. In the Dotclear world, '. 198 'we see it more like "One category, several tags." Therefore Dotclear can only import one '. 199 'category per post and will chose the lowest numbered one. If you want to keep a trace of '. 200 'every category, you can import them as tags, with an optional prefix.').'</p>'. 201 '<p>'.__('On the other hand, in WordPress, a post can not be uncategorized, and a '. 202 'default installation has a first category labelised <i>"Uncategorized"</i>.'. 203 'If you did not change that category, you can just ignore it while '. 204 'importing your blog, as Dotclear allows you to actually keep your posts '. 205 'uncategorized.').'</p>'. 206 '</div>'. 207 208 '<div class="col">'. 209 '<p><label for="ignore_first_cat" class="classic">'.form::checkbox('ignore_first_cat',1,$this->vars['ignore_first_cat']).' '. 210 __('Ignore the first category:').'</label></p>'. 211 '<p><label for="cat_import" class="classic">'.form::checkbox('cat_import',1,$this->vars['cat_import']).' '. 212 __('Import lowest numbered category on posts:').'</label></p>'. 213 '<p><label for="cat_as_tags" class="classic">'.form::checkbox('cat_as_tags',1,$this->vars['cat_as_tags']).' '. 214 __('Import all categories as tags:').'</label></p>'. 215 '<p><label for="cat_tags_prefix">'.__('Prefix such tags with:').'</label> '. 216 form::field('cat_tags_prefix',10,20,html::escapeHTML($this->vars['cat_tags_prefix'])).'</p>'. 217 '<p><label for="post_limit">'.__('Number of entries to import at once:').'</label> '. 218 form::field('post_limit',3,3,html::escapeHTML($this->vars['post_limit'])).'</p>'. 219 '</div>'. 220 221 '</div>'. 222 223 '<h3 class="clear vertical-separator">'.__('Content filters').'</h3>'. 224 '<p>'.__('You may want to process your post and/or comment content with the following filters.').'</p>'. 225 '<p><label for="post_formater">'.__('Post content formatter:').'</label> '. 226 form::combo('post_formater',$this->formaters,$this->vars['post_formater']).'</p>'. 227 '<p><label for="comment_formater">'.__('Comment content formatter:').'</label> ' 228 .form::combo('comment_formater',$this->formaters,$this->vars['comment_formater']).'</p>' 229 ); 230 break; 231 case 2: 232 printf($this->imForm(2,__('Importing users')), 233 $this->autoSubmit() 234 ); 235 break; 236 case 3: 237 printf($this->imForm(3,__('Importing categories')), 238 $this->autoSubmit() 239 ); 240 break; 241 case 4: 242 printf($this->imForm(4,__('Importing blogroll')), 243 $this->autoSubmit() 244 ); 245 break; 246 case 5: 247 $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset, 248 min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count); 249 printf($this->imForm(5,$t), 250 form::hidden(array('offset'),$this->post_offset). 251 $this->autoSubmit() 252 ); 253 break; 254 case 6: 255 echo 256 '<p class="message">'.__('Every newly imported user has received a random password '. 257 'and will need to ask for a new one by following the "I forgot my password" link on the login page '. 258 '(Their registered email address has to be valid.)').'</p>'. 259 $this->congratMessage(); 260 break; 261 } 262 } 263 264 # Simple form for step by step process 265 protected function imForm($step,$legend,$submit_value=null) 266 { 267 if (!$submit_value) { 268 $submit_value = __('next step').' >'; 269 } 270 271 return 272 '<form action="'.$this->getURL(true).'" method="post">'. 273 '<h3 class="vertical-separator">'.$legend.'</h3>'. 274 '<div>'.$this->core->formNonce(). 275 form::hidden(array('do'),'step'.$step). 276 '%s'.'</div>'. 277 '<p><input type="submit" value="'.$submit_value.'" /></p>'. 278 '<p class="form-note info">'.__('Depending on the size of your blog, it could take a few minutes.').'</p>'. 279 '</form>'; 280 } 281 282 # Error display 283 protected function error($e) 284 { 285 echo '<div class="error"><strong>'.__('Errors:').'</strong>'. 286 '<p>'.$e->getMessage().'</p></div>'; 287 } 288 289 # Database init 290 protected function db() 291 { 292 $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']); 293 294 $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'"); 295 if ($rs->isEmpty()) { 296 throw new Exception(__('WordPress tables not found')); 297 } 298 299 while ($rs->fetch()) { 300 $this->has_table[$rs->f(0)] = true; 301 } 302 303 # Set this to read data as they were written 304 try { 305 $db->execute('SET NAMES DEFAULT'); 306 } catch (Exception $e) {} 307 308 $db->execute('SET CHARACTER SET DEFAULT'); 309 $db->execute("SET COLLATION_CONNECTION = DEFAULT"); 310 $db->execute("SET COLLATION_SERVER = DEFAULT"); 311 $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); 312 $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); 313 314 $this->post_count = $db->select( 315 'SELECT COUNT(ID) FROM '.$this->vars['db_prefix'].'posts '. 316 'WHERE post_type = \'post\' OR post_type = \'page\'' 317 )->f(0); 318 319 return $db; 320 } 321 322 protected function cleanStr($str) 323 { 324 return text::cleanUTF8(@text::toUTF8($str)); 325 } 326 327 # Users import 328 protected function importUsers() 329 { 330 $db = $this->db(); 331 $prefix = $this->vars['db_prefix']; 332 $rs = $db->select('SELECT * FROM '.$prefix.'users'); 333 334 try 335 { 336 $this->con->begin(); 337 338 while ($rs->fetch()) 339 { 340 $user_login = preg_replace('/[^A-Za-z0-9@._-]/','-',$rs->user_login); 341 $this->vars['user_ids'][$rs->ID] = $user_login; 342 if (!$this->core->userExists($user_login)) 343 { 344 $cur = $this->con->openCursor($this->prefix.'user'); 345 $cur->user_id = $user_login; 346 $cur->user_pwd = crypt::createPassword(); 347 $cur->user_displayname = $rs->user_nicename; 348 $cur->user_email = $rs->user_email; 349 $cur->user_url = $rs->user_url; 350 $cur->user_creadt = $rs->user_registered; 351 $cur->user_lang = $this->core->blog->settings->system->lang; 352 $cur->user_tz = $this->core->blog->settings->system->blog_timezone; 353 $permissions = array(); 354 355 $rs_meta = $db->select('SELECT * FROM '.$prefix.'usermeta WHERE user_id = '.$rs->ID); 356 while ($rs_meta->fetch()) 357 { 358 switch ($rs_meta->meta_key) 359 { 360 case 'first_name': 361 $cur->user_firstname = $this->cleanStr($rs_meta->meta_value); 362 break; 363 case 'last_name': 364 $cur->user_name = $this->cleanStr($rs_meta->meta_value); 365 break; 366 case 'description': 367 $cur->user_desc = $this->cleanStr($rs_meta->meta_value); 368 break; 369 case 'rich_editing': 370 $cur->user_options = new ArrayObject(array( 371 'enable_wysiwyg' => $rs_meta->meta_value == 'true' ? true : false 372 )); 373 break; 374 case 'wp_user_level': 375 switch ($rs_meta->meta_value) 376 { 377 case '0': # Subscriber 378 $cur->user_status = 0; 379 break; 380 case '1': # Contributor 381 $permissions['usage'] = true; 382 $permissions['publish'] = true; 383 $permissions['delete'] = true; 384 break; 385 case '2': # Author 386 case '3': 387 case '4': 388 $permissions['contentadmin'] = true; 389 $permissions['media'] = true; 390 break; 391 case '5': # Editor 392 case '6': 393 case '7': 394 $permissions['contentadmin'] = true; 395 $permissions['categories'] = true; 396 $permissions['media_admin'] = true; 397 $permissions['pages'] = true; 398 $permissions['blogroll'] = true; 399 break; 400 case '8': # Administrator 401 case '9': 402 case '10': 403 $permissions['admin'] = true; 404 break; 405 } 406 break; 407 } 408 } 409 $this->core->addUser($cur); 410 $this->core->setUserBlogPermissions( 411 $cur->user_id, 412 $this->blog_id, 413 $permissions 414 ); 415 } 416 } 417 $this->con->commit(); 418 $db->close(); 419 } 420 catch (Exception $e) 421 { 422 $this->con->rollback(); 423 $db->close(); 424 throw $e; 425 } 426 } 427 428 # Categories import 429 protected function importCategories() 430 { 431 $db = $this->db(); 432 $prefix = $this->vars['db_prefix']; 433 $rs = $db->select( 434 'SELECT * FROM '.$prefix.'terms AS t, '.$prefix.'term_taxonomy AS x '. 435 'WHERE x.taxonomy = \'category\' '. 436 'AND t.term_id = x.term_id '. 437 ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). 438 'ORDER BY t.term_id ASC' 439 ); 440 441 try 442 { 443 $this->con->execute( 444 'DELETE FROM '.$this->prefix.'category '. 445 "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " 446 ); 447 448 $ord = 2; 449 while ($rs->fetch()) 450 { 451 $cur = $this->con->openCursor($this->prefix.'category'); 452 $cur->blog_id = $this->blog_id; 453 $cur->cat_title = $this->cleanStr($rs->name); 454 $cur->cat_desc = $this->cleanStr($rs->description); 455 $cur->cat_url = $this->cleanStr($rs->slug); 456 $cur->cat_lft = $ord++; 457 $cur->cat_rgt = $ord++; 458 459 $cur->cat_id = $this->con->select( 460 'SELECT MAX(cat_id) FROM '.$this->prefix.'category' 461 )->f(0) + 1; 462 $this->vars['cat_ids'][$rs->term_id] = $cur->cat_id; 463 $cur->insert(); 464 } 465 466 $db->close(); 467 } 468 catch (Exception $e) 469 { 470 $db->close(); 471 throw $e; 472 } 473 } 474 475 # Blogroll import 476 protected function importLinks() 477 { 478 $db = $this->db(); 479 $prefix = $this->vars['db_prefix']; 480 $rs = $db->select('SELECT * FROM '.$prefix.'links ORDER BY link_id ASC'); 481 482 try 483 { 484 $this->con->execute( 485 'DELETE FROM '.$this->prefix.'link '. 486 "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " 487 ); 488 489 while ($rs->fetch()) 490 { 491 $cur = $this->con->openCursor($this->prefix.'link'); 492 $cur->blog_id = $this->blog_id; 493 $cur->link_href = $this->cleanStr($rs->link_url); 494 $cur->link_title = $this->cleanStr($rs->link_name); 495 $cur->link_desc = $this->cleanStr($rs->link_description); 496 $cur->link_xfn = $this->cleanStr($rs->link_rel); 497 498 $cur->link_id = $this->con->select( 499 'SELECT MAX(link_id) FROM '.$this->prefix.'link' 500 )->f(0) + 1; 501 $cur->insert(); 502 } 503 504 $db->close(); 505 } 506 catch (Exception $e) 507 { 508 $db->close(); 509 throw $e; 510 } 511 } 512 513 # Entries import 514 protected function importPosts(&$percent) 515 { 516 $db = $this->db(); 517 $prefix = $this->vars['db_prefix']; 518 519 $plink = $db->select( 520 'SELECT option_value FROM '.$prefix.'options '. 521 "WHERE option_name = 'permalink_structure'" 522 )->option_value; 523 if ($plink) { 524 $this->vars['permalink_template'] = substr($plink,1); 525 } 526 527 $rs = $db->select( 528 'SELECT * FROM '.$prefix.'posts '. 529 'WHERE post_type = \'post\' OR post_type = \'page\' '. 530 'ORDER BY ID ASC '. 531 $db->limit($this->post_offset,$this->post_limit) 532 ); 533 534 try 535 { 536 if ($this->post_offset == 0) 537 { 538 $this->con->execute( 539 'DELETE FROM '.$this->prefix.'post '. 540 "WHERE blog_id = '".$this->con->escape($this->blog_id)."' " 541 ); 542 } 543 544 while ($rs->fetch()) { 545 $this->importPost($rs,$db); 546 } 547 548 $db->close(); 549 } 550 catch (Exception $e) 551 { 552 $db->close(); 553 throw $e; 554 } 555 556 if ($rs->count() < $this->post_limit) { 557 return -1; 558 } else { 559 $this->post_offset += $this->post_limit; 560 } 561 562 if ($this->post_offset > $this->post_count) { 563 $percent = 100; 564 } else { 565 $percent = $this->post_offset * 100 / $this->post_count; 566 } 567 } 568 569 protected function importPost($rs,$db) 570 { 571 $post_date = !@strtotime($rs->post_date) ? '1970-01-01 00:00' : $rs->post_date; 572 if (!isset($this->vars['user_ids'][$rs->post_author])) { 573 $user_id = $this->core->auth->userID(); 574 } else { 575 $user_id = $this->vars['user_ids'][$rs->post_author]; 576 } 577 578 $cur = $this->con->openCursor($this->prefix.'post'); 579 $cur->blog_id = $this->blog_id; 580 $cur->user_id = $user_id; 581 $cur->post_dt = $post_date; 582 $cur->post_creadt = $post_date; 583 $cur->post_upddt = $rs->post_modified; 584 $cur->post_title = $this->cleanStr($rs->post_title); 585 586 if (!$cur->post_title) { 587 $cur->post_title = 'No title'; 588 } 589 590 if ($this->vars['cat_import'] || $this->vars['cat_as_tags']) 591 { 592 $old_cat_ids = $db->select( 593 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. 594 $this->vars['db_prefix'].'term_taxonomy AS x, '. 595 $this->vars['db_prefix'].'term_relationships AS r '. 596 'WHERE t.term_id = x.term_id '. 597 ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : ''). 598 'AND x.taxonomy = \'category\' '. 599 'AND t.term_id = r.term_taxonomy_id '. 600 'AND r.object_id ='.$rs->ID. 601 ' ORDER BY t.term_id ASC ' 602 ); 603 if (!$old_cat_ids->isEmpty() && $this->vars['cat_import']) 604 { 605 $cur->cat_id = $this->vars['cat_ids'][(integer) $old_cat_ids->term_id]; 606 } 607 } 608 609 $permalink_infos = array( 610 date('Y',strtotime($cur->post_dt)), 611 date('m',strtotime($cur->post_dt)), 612 date('d',strtotime($cur->post_dt)), 613 date('H',strtotime($cur->post_dt)), 614 date('i',strtotime($cur->post_dt)), 615 date('s',strtotime($cur->post_dt)), 616 $rs->post_name, 617 $rs->ID, 618 $cur->cat_id, 619 $cur->user_id 620 ); 621 $cur->post_url = str_replace( 622 $this->vars['permalink_tags'], 623 $permalink_infos, 624 $rs->post_type== 'post' ? $this->vars['permalink_template'] : '%postname%' 625 ); 626 $cur->post_url = substr($cur->post_url,0,255); 627 628 if (!$cur->post_url) { 629 $cur->post_url = $rs->ID; 630 } 631 632 $cur->post_format = $this->vars['post_formater']; 633 $_post_content = explode('<!--more-->',$rs->post_content,2); 634 if (count($_post_content) == 1) { 635 $cur->post_excerpt = NULL; 636 $cur->post_content = $this->cleanStr(array_shift($_post_content)); 637 } else { 638 $cur->post_excerpt = $this->cleanStr(array_shift($_post_content)); 639 $cur->post_content = $this->cleanStr(array_shift($_post_content)); 640 } 641 642 $cur->post_content_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_content); 643 $cur->post_excerpt_xhtml = $this->core->callFormater($this->vars['post_formater'],$cur->post_excerpt); 644 645 switch ($rs->post_status) 646 { 647 case 'publish': 648 $cur->post_status = 1; 649 break; 650 case 'draft': 651 $cur->post_status = 0; 652 break; 653 case 'pending': 654 $cur->post_status = -2; 655 break; 656 default: 657 $cur->post_status = -2; 658 } 659 $cur->post_type = $rs->post_type; 660 $cur->post_password = $rs->post_password ?: NULL; 661 $cur->post_open_comment = $rs->comment_status == 'open' ? 1 : 0; 662 $cur->post_open_tb = $rs->ping_status == 'open' ? 1 : 0; 663 664 $cur->post_words = implode(' ',text::splitWords( 665 $cur->post_title.' '. 666 $cur->post_excerpt_xhtml.' '. 667 $cur->post_content_xhtml 668 )); 669 670 $cur->post_id = $this->con->select( 671 'SELECT MAX(post_id) FROM '.$this->prefix.'post' 672 )->f(0) + 1; 673 674 $cur->post_url = $this->core->blog->getPostURL($cur->post_url,$cur->post_dt,$cur->post_title,$cur->post_id); 675 676 $cur->insert(); 677 $this->importComments($rs->ID,$cur->post_id,$db); 678 $this->importPings($rs->ID,$cur->post_id,$db); 679 680 # Create tags 681 $this->importTags($rs->ID,$cur->post_id,$db); 682 683 if (isset($old_cat_ids)) 684 { 685 if (!$old_cat_ids->isEmpty() && $this->vars['cat_as_tags']) 686 { 687 $old_cat_ids->moveStart(); 688 while ($old_cat_ids->fetch()) { 689 $this->core->meta->setPostMeta($cur->post_id,'tag',$this->cleanStr($this->vars['cat_tags_prefix'].$old_cat_ids->name)); 690 } 691 } 692 } 693 } 694 695 # Comments import 696 protected function importComments($post_id,$new_post_id,$db) 697 { 698 $count_c = $count_t = 0; 699 700 $rs = $db->select( 701 'SELECT * FROM '.$this->vars['db_prefix'].'comments '. 702 'WHERE comment_post_ID = '.(integer) $post_id.' ' 703 ); 704 705 while ($rs->fetch()) 706 { 707 $cur = $this->con->openCursor($this->prefix.'comment'); 708 $cur->post_id = (integer) $new_post_id; 709 $cur->comment_author = $this->cleanStr($rs->comment_author); 710 $cur->comment_status = (integer) $rs->comment_approved ; 711 $cur->comment_dt = $rs->comment_date; 712 $cur->comment_email = $this->cleanStr($rs->comment_author_email); 713 $cur->comment_content = $this->core->callFormater($this->vars['comment_formater'],$this->cleanStr($rs->comment_content)); 714 $cur->comment_ip = $rs->comment_author_IP; 715 $cur->comment_trackback = $rs->comment_type == 'trackback' ? 1 : 0; 716 $cur->comment_site = substr($this->cleanStr($rs->comment_author_url),0,255); 717 if ($cur->comment_site == '') $cur->comment_site = NULL; 718 719 if ($rs->comment_approved == 'spam') { 720 $cur->comment_status = -2; 721 } 722 723 $cur->comment_words = implode(' ',text::splitWords($cur->comment_content)); 724 725 $cur->comment_id = $this->con->select( 726 'SELECT MAX(comment_id) FROM '.$this->prefix.'comment' 727 )->f(0) + 1; 728 729 $cur->insert(); 730 731 if ($cur->comment_trackback && $cur->comment_status == 1) { 732 $count_t++; 733 } elseif ($cur->comment_status == 1) { 734 $count_c++; 735 } 736 } 737 738 if ($count_t > 0 || $count_c > 0) 739 { 740 $this->con->execute( 741 'UPDATE '.$this->prefix.'post SET '. 742 'nb_comment = '.$count_c.', '. 743 'nb_trackback = '.$count_t.' '. 744 'WHERE post_id = '.(integer) $new_post_id.' ' 745 ); 746 } 747 } 748 749 # Pings import 750 protected function importPings($post_id,$new_post_id,$db) 751 { 752 $urls = array(); 753 $pings = array(); 754 755 $rs = $db->select( 756 'SELECT pinged FROM '.$this->vars['db_prefix'].'posts '. 757 'WHERE ID = '.(integer) $post_id 758 ); 759 $pings = explode ("\n",$rs->pinged); 760 unset ($pings[0]); 761 762 foreach($pings as $ping_url) 763 { 764 $url = $this->cleanStr($ping_url); 765 if (isset($urls[$url])) { 766 continue; 767 } 768 769 $cur = $this->con->openCursor($this->prefix.'ping'); 770 $cur->post_id = (integer) $new_post_id; 771 $cur->ping_url = $url; 772 $cur->insert(); 773 774 $urls[$url] = true; 775 } 776 } 777 778 # Meta import 779 protected function importTags($post_id,$new_post_id,$db) 780 { 781 $rs = $db->select( 782 'SELECT * FROM '.$this->vars['db_prefix'].'terms AS t, '. 783 $this->vars['db_prefix'].'term_taxonomy AS x, '. 784 $this->vars['db_prefix'].'term_relationships AS r '. 785 'WHERE t.term_id = x.term_id '. 786 'AND x.taxonomy = \'post_tag\' '. 787 'AND t.term_id = r.term_taxonomy_id '. 788 'AND r.object_id ='.$post_id. 789 ' ORDER BY t.term_id ASC' 790 ); 791 792 if ($rs->isEmpty()) { 793 return; 794 } 795 796 while ($rs->fetch()) { 797 $this->core->meta->setPostMeta($new_post_id,'tag',$this->cleanStr($rs->name)); 798 } 799 } 16 protected $con; 17 protected $prefix; 18 protected $blog_id; 19 20 protected $action = null; 21 protected $step = 1; 22 23 protected $post_offset = 0; 24 protected $post_limit = 20; 25 protected $post_count = 0; 26 27 protected $has_table = array(); 28 29 protected $vars; 30 protected $base_vars = array( 31 'db_host' => '', 32 'db_name' => '', 33 'db_user' => '', 34 'db_pwd' => '', 35 'db_prefix' => 'wp_', 36 'ignore_first_cat' => 1, 37 'cat_import' => 1, 38 'cat_as_tags' => '', 39 'cat_tags_prefix' => 'cat: ', 40 'post_limit' => 20, 41 'post_formater' => 'xhtml', 42 'comment_formater' => 'xhtml', 43 'user_ids' => array(), 44 'cat_ids' => array(), 45 'permalink_template' => 'p=%post_id%', 46 'permalink_tags' => array( 47 '%year%', 48 '%monthnum%', 49 '%day%', 50 '%hour%', 51 '%minute%', 52 '%second%', 53 '%postname%', 54 '%post_id%', 55 '%category%', 56 '%author%' 57 ) 58 ); 59 protected $formaters; 60 61 protected function setInfo() 62 { 63 $this->type = 'import'; 64 $this->name = __('WordPress import'); 65 $this->description = __('Import a WordPress installation into your current blog.'); 66 } 67 68 public function init() 69 { 70 $this->con = &$this->core->con; 71 $this->prefix = $this->core->prefix; 72 $this->blog_id = $this->core->blog->id; 73 74 if (!isset($_SESSION['wp_import_vars'])) { 75 $_SESSION['wp_import_vars'] = $this->base_vars; 76 } 77 $this->vars = &$_SESSION['wp_import_vars']; 78 79 if ($this->vars['post_limit'] > 0) { 80 $this->post_limit = $this->vars['post_limit']; 81 } 82 83 $this->formaters = dcAdminCombos::getFormatersCombo(); 84 } 85 86 public function resetVars() 87 { 88 $this->vars = $this->base_vars; 89 unset($_SESSION['wp_import_vars']); 90 } 91 92 public function process($do) 93 { 94 $this->action = $do; 95 } 96 97 # We handle process in another way to always display something to 98 # user 99 protected function guiprocess($do) 100 { 101 switch ($do) { 102 case 'step1': 103 $this->vars['db_host'] = $_POST['db_host']; 104 $this->vars['db_name'] = $_POST['db_name']; 105 $this->vars['db_user'] = $_POST['db_user']; 106 $this->vars['db_pwd'] = $_POST['db_pwd']; 107 $this->vars['db_prefix'] = $_POST['db_prefix']; 108 $this->vars['ignore_first_cat'] = isset($_POST['ignore_first_cat']); 109 $this->vars['cat_import'] = isset($_POST['cat_import']); 110 $this->vars['cat_as_tags'] = isset($_POST['cat_as_tags']); 111 $this->vars['cat_tags_prefix'] = $_POST['cat_tags_prefix']; 112 $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0; 113 $this->vars['post_formater'] = isset($this->formaters[$_POST['post_formater']]) ? $_POST['post_formater'] : 'xhtml'; 114 $this->vars['comment_formater'] = isset($this->formaters[$_POST['comment_formater']]) ? $_POST['comment_formater'] : 'xhtml'; 115 $db = $this->db(); 116 $db->close(); 117 $this->step = 2; 118 echo $this->progressBar(1); 119 break; 120 case 'step2': 121 $this->step = 2; 122 $this->importUsers(); 123 $this->step = 3; 124 echo $this->progressBar(3); 125 break; 126 case 'step3': 127 $this->step = 3; 128 $this->importCategories(); 129 if ($this->core->plugins->moduleExists('blogroll')) { 130 $this->step = 4; 131 echo $this->progressBar(5); 132 } else { 133 $this->step = 5; 134 echo $this->progressBar(7); 135 } 136 break; 137 case 'step4': 138 $this->step = 4; 139 $this->importLinks(); 140 $this->step = 5; 141 echo $this->progressBar(7); 142 break; 143 case 'step5': 144 $this->step = 5; 145 $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0; 146 if ($this->importPosts($percent) === -1) { 147 http::redirect($this->getURL() . '&do=ok'); 148 } else { 149 echo $this->progressBar(ceil($percent * 0.93) + 7); 150 } 151 break; 152 case 'ok': 153 $this->resetVars(); 154 $this->core->blog->triggerBlog(); 155 $this->step = 6; 156 echo $this->progressBar(100); 157 break; 158 } 159 } 160 161 public function gui() 162 { 163 try { 164 $this->guiprocess($this->action); 165 } catch (Exception $e) { 166 $this->error($e); 167 } 168 169 switch ($this->step) { 170 case 1: 171 echo 172 '<p>' . sprintf(__('This will import your WordPress content as new content in the current blog: %s.'), 173 '<strong>' . html::escapeHTML($this->core->blog->name) . '</strong>') . '</p>' . 174 '<p class="warning">' . __('Please note that this process ' . 175 'will empty your categories, blogroll, entries and comments on the current blog.') . '</p>'; 176 177 printf($this->imForm(1, __('General information'), __('Import my blog now')), 178 '<p>' . __('We first need some information about your old WordPress installation.') . '</p>' . 179 '<p><label for="db_host">' . __('Database Host Name:') . '</label> ' . 180 form::field('db_host', 30, 255, html::escapeHTML($this->vars['db_host'])) . '</p>' . 181 '<p><label for="db_name">' . __('Database Name:', html::escapeHTML($this->vars['db_name'])) . '</label> ' . 182 form::field('db_name', 30, 255, html::escapeHTML($this->vars['db_name'])) . '</p>' . 183 '<p><label for="db_user">' . __('Database User Name:') . '</label> ' . 184 form::field('db_user', 30, 255, html::escapeHTML($this->vars['db_user'])) . '</p>' . 185 '<p><label for="db_pwd">' . __('Database Password:') . '</label> ' . 186 form::password('db_pwd', 30, 255) . '</p>' . 187 '<p><label for="db_prefix">' . __('Database Tables Prefix:') . '</label> ' . 188 form::field('db_prefix', 30, 255, html::escapeHTML($this->vars['db_prefix'])) . '</p>' . 189 190 '<h3 class="vertical-separator">' . __('Entries import options') . '</h3>' . 191 '<div class="two-cols">' . 192 193 '<div class="col">' . 194 '<p>' . __('WordPress and Dotclear\'s handling of categories are quite different. ' . 195 'You can assign several categories to a single post in WordPress. In the Dotclear world, ' . 196 'we see it more like "One category, several tags." Therefore Dotclear can only import one ' . 197 'category per post and will chose the lowest numbered one. If you want to keep a trace of ' . 198 'every category, you can import them as tags, with an optional prefix.') . '</p>' . 199 '<p>' . __('On the other hand, in WordPress, a post can not be uncategorized, and a ' . 200 'default installation has a first category labelised <i>"Uncategorized"</i>.' . 201 'If you did not change that category, you can just ignore it while ' . 202 'importing your blog, as Dotclear allows you to actually keep your posts ' . 203 'uncategorized.') . '</p>' . 204 '</div>' . 205 206 '<div class="col">' . 207 '<p><label for="ignore_first_cat" class="classic">' . form::checkbox('ignore_first_cat', 1, $this->vars['ignore_first_cat']) . ' ' . 208 __('Ignore the first category:') . '</label></p>' . 209 '<p><label for="cat_import" class="classic">' . form::checkbox('cat_import', 1, $this->vars['cat_import']) . ' ' . 210 __('Import lowest numbered category on posts:') . '</label></p>' . 211 '<p><label for="cat_as_tags" class="classic">' . form::checkbox('cat_as_tags', 1, $this->vars['cat_as_tags']) . ' ' . 212 __('Import all categories as tags:') . '</label></p>' . 213 '<p><label for="cat_tags_prefix">' . __('Prefix such tags with:') . '</label> ' . 214 form::field('cat_tags_prefix', 10, 20, html::escapeHTML($this->vars['cat_tags_prefix'])) . '</p>' . 215 '<p><label for="post_limit">' . __('Number of entries to import at once:') . '</label> ' . 216 form::number('post_limit', 0, 999, html::escapeHTML($this->vars['post_limit'])) . '</p>' . 217 '</div>' . 218 219 '</div>' . 220 221 '<h3 class="clear vertical-separator">' . __('Content filters') . '</h3>' . 222 '<p>' . __('You may want to process your post and/or comment content with the following filters.') . '</p>' . 223 '<p><label for="post_formater">' . __('Post content formatter:') . '</label> ' . 224 form::combo('post_formater', $this->formaters, $this->vars['post_formater']) . '</p>' . 225 '<p><label for="comment_formater">' . __('Comment content formatter:') . '</label> ' 226 . form::combo('comment_formater', $this->formaters, $this->vars['comment_formater']) . '</p>' 227 ); 228 break; 229 case 2: 230 printf($this->imForm(2, __('Importing users')), 231 $this->autoSubmit() 232 ); 233 break; 234 case 3: 235 printf($this->imForm(3, __('Importing categories')), 236 $this->autoSubmit() 237 ); 238 break; 239 case 4: 240 printf($this->imForm(4, __('Importing blogroll')), 241 $this->autoSubmit() 242 ); 243 break; 244 case 5: 245 $t = sprintf(__('Importing entries from %d to %d / %d'), $this->post_offset, 246 min(array($this->post_offset + $this->post_limit, $this->post_count)), $this->post_count); 247 printf($this->imForm(5, $t), 248 form::hidden(array('offset'), $this->post_offset) . 249 $this->autoSubmit() 250 ); 251 break; 252 case 6: 253 echo 254 '<p class="message">' . __('Every newly imported user has received a random password ' . 255 'and will need to ask for a new one by following the "I forgot my password" link on the login page ' . 256 '(Their registered email address has to be valid.)') . '</p>' . 257 $this->congratMessage(); 258 break; 259 } 260 } 261 262 # Simple form for step by step process 263 protected function imForm($step, $legend, $submit_value = null) 264 { 265 if (!$submit_value) { 266 $submit_value = __('next step') . ' >'; 267 } 268 269 return 270 '<form action="' . $this->getURL(true) . '" method="post">' . 271 '<h3 class="vertical-separator">' . $legend . '</h3>' . 272 '<div>' . $this->core->formNonce() . 273 form::hidden(array('do'), 'step' . $step) . 274 '%s' . '</div>' . 275 '<p><input type="submit" value="' . $submit_value . '" /></p>' . 276 '<p class="form-note info">' . __('Depending on the size of your blog, it could take a few minutes.') . '</p>' . 277 '</form>'; 278 } 279 280 # Error display 281 protected function error($e) 282 { 283 echo '<div class="error"><strong>' . __('Errors:') . '</strong>' . 284 '<p>' . $e->getMessage() . '</p></div>'; 285 } 286 287 # Database init 288 protected function db() 289 { 290 $db = dbLayer::init('mysql', $this->vars['db_host'], $this->vars['db_name'], $this->vars['db_user'], $this->vars['db_pwd']); 291 292 $rs = $db->select("SHOW TABLES LIKE '" . $this->vars['db_prefix'] . "%'"); 293 if ($rs->isEmpty()) { 294 throw new Exception(__('WordPress tables not found')); 295 } 296 297 while ($rs->fetch()) { 298 $this->has_table[$rs->f(0)] = true; 299 } 300 301 # Set this to read data as they were written 302 try { 303 $db->execute('SET NAMES DEFAULT'); 304 } catch (Exception $e) {} 305 306 $db->execute('SET CHARACTER SET DEFAULT'); 307 $db->execute("SET COLLATION_CONNECTION = DEFAULT"); 308 $db->execute("SET COLLATION_SERVER = DEFAULT"); 309 $db->execute("SET CHARACTER_SET_SERVER = DEFAULT"); 310 $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT"); 311 312 $this->post_count = $db->select( 313 'SELECT COUNT(ID) FROM ' . $this->vars['db_prefix'] . 'posts ' . 314 'WHERE post_type = \'post\' OR post_type = \'page\'' 315 )->f(0); 316 317 return $db; 318 } 319 320 protected function cleanStr($str) 321 { 322 return text::cleanUTF8(@text::toUTF8($str)); 323 } 324 325 # Users import 326 protected function importUsers() 327 { 328 $db = $this->db(); 329 $prefix = $this->vars['db_prefix']; 330 $rs = $db->select('SELECT * FROM ' . $prefix . 'users'); 331 332 try 333 { 334 $this->con->begin(); 335 336 while ($rs->fetch()) { 337 $user_login = preg_replace('/[^A-Za-z0-9@._-]/', '-', $rs->user_login); 338 $this->vars['user_ids'][$rs->ID] = $user_login; 339 if (!$this->core->userExists($user_login)) { 340 $cur = $this->con->openCursor($this->prefix . 'user'); 341 $cur->user_id = $user_login; 342 $cur->user_pwd = crypt::createPassword(); 343 $cur->user_displayname = $rs->user_nicename; 344 $cur->user_email = $rs->user_email; 345 $cur->user_url = $rs->user_url; 346 $cur->user_creadt = $rs->user_registered; 347 $cur->user_lang = $this->core->blog->settings->system->lang; 348 $cur->user_tz = $this->core->blog->settings->system->blog_timezone; 349 $permissions = array(); 350 351 $rs_meta = $db->select('SELECT * FROM ' . $prefix . 'usermeta WHERE user_id = ' . $rs->ID); 352 while ($rs_meta->fetch()) { 353 switch ($rs_meta->meta_key) { 354 case 'first_name': 355 $cur->user_firstname = $this->cleanStr($rs_meta->meta_value); 356 break; 357 case 'last_name': 358 $cur->user_name = $this->cleanStr($rs_meta->meta_value); 359 break; 360 case 'description': 361 $cur->user_desc = $this->cleanStr($rs_meta->meta_value); 362 break; 363 case 'rich_editing': 364 $cur->user_options = new ArrayObject(array( 365 'enable_wysiwyg' => $rs_meta->meta_value == 'true' ? true : false 366 )); 367 break; 368 case 'wp_user_level': 369 switch ($rs_meta->meta_value) { 370 case '0': # Subscriber 371 $cur->user_status = 0; 372 break; 373 case '1': # Contributor 374 $permissions['usage'] = true; 375 $permissions['publish'] = true; 376 $permissions['delete'] = true; 377 break; 378 case '2': # Author 379 case '3': 380 case '4': 381 $permissions['contentadmin'] = true; 382 $permissions['media'] = true; 383 break; 384 case '5': # Editor 385 case '6': 386 case '7': 387 $permissions['contentadmin'] = true; 388 $permissions['categories'] = true; 389 $permissions['media_admin'] = true; 390 $permissions['pages'] = true; 391 $permissions['blogroll'] = true; 392 break; 393 case '8': # Administrator 394 case '9': 395 case '10': 396 $permissions['admin'] = true; 397 break; 398 } 399 break; 400 } 401 } 402 $this->core->addUser($cur); 403 $this->core->setUserBlogPermissions( 404 $cur->user_id, 405 $this->blog_id, 406 $permissions 407 ); 408 } 409 } 410 $this->con->commit(); 411 $db->close(); 412 } catch (Exception $e) { 413 $this->con->rollback(); 414 $db->close(); 415 throw $e; 416 } 417 } 418 419 # Categories import 420 protected function importCategories() 421 { 422 $db = $this->db(); 423 $prefix = $this->vars['db_prefix']; 424 $rs = $db->select( 425 'SELECT * FROM ' . $prefix . 'terms AS t, ' . $prefix . 'term_taxonomy AS x ' . 426 'WHERE x.taxonomy = \'category\' ' . 427 'AND t.term_id = x.term_id ' . 428 ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : '') . 429 'ORDER BY t.term_id ASC' 430 ); 431 432 try 433 { 434 $this->con->execute( 435 'DELETE FROM ' . $this->prefix . 'category ' . 436 "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' " 437 ); 438 439 $ord = 2; 440 while ($rs->fetch()) { 441 $cur = $this->con->openCursor($this->prefix . 'category'); 442 $cur->blog_id = $this->blog_id; 443 $cur->cat_title = $this->cleanStr($rs->name); 444 $cur->cat_desc = $this->cleanStr($rs->description); 445 $cur->cat_url = $this->cleanStr($rs->slug); 446 $cur->cat_lft = $ord++; 447 $cur->cat_rgt = $ord++; 448 449 $cur->cat_id = $this->con->select( 450 'SELECT MAX(cat_id) FROM ' . $this->prefix . 'category' 451 )->f(0) + 1; 452 $this->vars['cat_ids'][$rs->term_id] = $cur->cat_id; 453 $cur->insert(); 454 } 455 456 $db->close(); 457 } catch (Exception $e) { 458 $db->close(); 459 throw $e; 460 } 461 } 462 463 # Blogroll import 464 protected function importLinks() 465 { 466 $db = $this->db(); 467 $prefix = $this->vars['db_prefix']; 468 $rs = $db->select('SELECT * FROM ' . $prefix . 'links ORDER BY link_id ASC'); 469 470 try 471 { 472 $this->con->execute( 473 'DELETE FROM ' . $this->prefix . 'link ' . 474 "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' " 475 ); 476 477 while ($rs->fetch()) { 478 $cur = $this->con->openCursor($this->prefix . 'link'); 479 $cur->blog_id = $this->blog_id; 480 $cur->link_href = $this->cleanStr($rs->link_url); 481 $cur->link_title = $this->cleanStr($rs->link_name); 482 $cur->link_desc = $this->cleanStr($rs->link_description); 483 $cur->link_xfn = $this->cleanStr($rs->link_rel); 484 485 $cur->link_id = $this->con->select( 486 'SELECT MAX(link_id) FROM ' . $this->prefix . 'link' 487 )->f(0) + 1; 488 $cur->insert(); 489 } 490 491 $db->close(); 492 } catch (Exception $e) { 493 $db->close(); 494 throw $e; 495 } 496 } 497 498 # Entries import 499 protected function importPosts(&$percent) 500 { 501 $db = $this->db(); 502 $prefix = $this->vars['db_prefix']; 503 504 $plink = $db->select( 505 'SELECT option_value FROM ' . $prefix . 'options ' . 506 "WHERE option_name = 'permalink_structure'" 507 )->option_value; 508 if ($plink) { 509 $this->vars['permalink_template'] = substr($plink, 1); 510 } 511 512 $rs = $db->select( 513 'SELECT * FROM ' . $prefix . 'posts ' . 514 'WHERE post_type = \'post\' OR post_type = \'page\' ' . 515 'ORDER BY ID ASC ' . 516 $db->limit($this->post_offset, $this->post_limit) 517 ); 518 519 try 520 { 521 if ($this->post_offset == 0) { 522 $this->con->execute( 523 'DELETE FROM ' . $this->prefix . 'post ' . 524 "WHERE blog_id = '" . $this->con->escape($this->blog_id) . "' " 525 ); 526 } 527 528 while ($rs->fetch()) { 529 $this->importPost($rs, $db); 530 } 531 532 $db->close(); 533 } catch (Exception $e) { 534 $db->close(); 535 throw $e; 536 } 537 538 if ($rs->count() < $this->post_limit) { 539 return -1; 540 } else { 541 $this->post_offset += $this->post_limit; 542 } 543 544 if ($this->post_offset > $this->post_count) { 545 $percent = 100; 546 } else { 547 $percent = $this->post_offset * 100 / $this->post_count; 548 } 549 } 550 551 protected function importPost($rs, $db) 552 { 553 $post_date = !@strtotime($rs->post_date) ? '1970-01-01 00:00' : $rs->post_date; 554 if (!isset($this->vars['user_ids'][$rs->post_author])) { 555 $user_id = $this->core->auth->userID(); 556 } else { 557 $user_id = $this->vars['user_ids'][$rs->post_author]; 558 } 559 560 $cur = $this->con->openCursor($this->prefix . 'post'); 561 $cur->blog_id = $this->blog_id; 562 $cur->user_id = $user_id; 563 $cur->post_dt = $post_date; 564 $cur->post_creadt = $post_date; 565 $cur->post_upddt = $rs->post_modified; 566 $cur->post_title = $this->cleanStr($rs->post_title); 567 568 if (!$cur->post_title) { 569 $cur->post_title = 'No title'; 570 } 571 572 if ($this->vars['cat_import'] || $this->vars['cat_as_tags']) { 573 $old_cat_ids = $db->select( 574 'SELECT * FROM ' . $this->vars['db_prefix'] . 'terms AS t, ' . 575 $this->vars['db_prefix'] . 'term_taxonomy AS x, ' . 576 $this->vars['db_prefix'] . 'term_relationships AS r ' . 577 'WHERE t.term_id = x.term_id ' . 578 ($this->vars['ignore_first_cat'] ? 'AND t.term_id <> 1 ' : '') . 579 'AND x.taxonomy = \'category\' ' . 580 'AND t.term_id = r.term_taxonomy_id ' . 581 'AND r.object_id =' . $rs->ID . 582 ' ORDER BY t.term_id ASC ' 583 ); 584 if (!$old_cat_ids->isEmpty() && $this->vars['cat_import']) { 585 $cur->cat_id = $this->vars['cat_ids'][(integer) $old_cat_ids->term_id]; 586 } 587 } 588 589 $permalink_infos = array( 590 date('Y', strtotime($cur->post_dt)), 591 date('m', strtotime($cur->post_dt)), 592 date('d', strtotime($cur->post_dt)), 593 date('H', strtotime($cur->post_dt)), 594 date('i', strtotime($cur->post_dt)), 595 date('s', strtotime($cur->post_dt)), 596 $rs->post_name, 597 $rs->ID, 598 $cur->cat_id, 599 $cur->user_id 600 ); 601 $cur->post_url = str_replace( 602 $this->vars['permalink_tags'], 603 $permalink_infos, 604 $rs->post_type == 'post' ? $this->vars['permalink_template'] : '%postname%' 605 ); 606 $cur->post_url = substr($cur->post_url, 0, 255); 607 608 if (!$cur->post_url) { 609 $cur->post_url = $rs->ID; 610 } 611 612 $cur->post_format = $this->vars['post_formater']; 613 $_post_content = explode('<!--more-->', $rs->post_content, 2); 614 if (count($_post_content) == 1) { 615 $cur->post_excerpt = null; 616 $cur->post_content = $this->cleanStr(array_shift($_post_content)); 617 } else { 618 $cur->post_excerpt = $this->cleanStr(array_shift($_post_content)); 619 $cur->post_content = $this->cleanStr(array_shift($_post_content)); 620 } 621 622 $cur->post_content_xhtml = $this->core->callFormater($this->vars['post_formater'], $cur->post_content); 623 $cur->post_excerpt_xhtml = $this->core->callFormater($this->vars['post_formater'], $cur->post_excerpt); 624 625 switch ($rs->post_status) { 626 case 'publish': 627 $cur->post_status = 1; 628 break; 629 case 'draft': 630 $cur->post_status = 0; 631 break; 632 case 'pending': 633 $cur->post_status = -2; 634 break; 635 default: 636 $cur->post_status = -2; 637 } 638 $cur->post_type = $rs->post_type; 639 $cur->post_password = $rs->post_password ?: null; 640 $cur->post_open_comment = $rs->comment_status == 'open' ? 1 : 0; 641 $cur->post_open_tb = $rs->ping_status == 'open' ? 1 : 0; 642 643 $cur->post_words = implode(' ', text::splitWords( 644 $cur->post_title . ' ' . 645 $cur->post_excerpt_xhtml . ' ' . 646 $cur->post_content_xhtml 647 )); 648 649 $cur->post_id = $this->con->select( 650 'SELECT MAX(post_id) FROM ' . $this->prefix . 'post' 651 )->f(0) + 1; 652 653 $cur->post_url = $this->core->blog->getPostURL($cur->post_url, $cur->post_dt, $cur->post_title, $cur->post_id); 654 655 $cur->insert(); 656 $this->importComments($rs->ID, $cur->post_id, $db); 657 $this->importPings($rs->ID, $cur->post_id, $db); 658 659 # Create tags 660 $this->importTags($rs->ID, $cur->post_id, $db); 661 662 if (isset($old_cat_ids)) { 663 if (!$old_cat_ids->isEmpty() && $this->vars['cat_as_tags']) { 664 $old_cat_ids->moveStart(); 665 while ($old_cat_ids->fetch()) { 666 $this->core->meta->setPostMeta($cur->post_id, 'tag', $this->cleanStr($this->vars['cat_tags_prefix'] . $old_cat_ids->name)); 667 } 668 } 669 } 670 } 671 672 # Comments import 673 protected function importComments($post_id, $new_post_id, $db) 674 { 675 $count_c = $count_t = 0; 676 677 $rs = $db->select( 678 'SELECT * FROM ' . $this->vars['db_prefix'] . 'comments ' . 679 'WHERE comment_post_ID = ' . (integer) $post_id . ' ' 680 ); 681 682 while ($rs->fetch()) { 683 $cur = $this->con->openCursor($this->prefix . 'comment'); 684 $cur->post_id = (integer) $new_post_id; 685 $cur->comment_author = $this->cleanStr($rs->comment_author); 686 $cur->comment_status = (integer) $rs->comment_approved; 687 $cur->comment_dt = $rs->comment_date; 688 $cur->comment_email = $this->cleanStr($rs->comment_author_email); 689 $cur->comment_content = $this->core->callFormater($this->vars['comment_formater'], $this->cleanStr($rs->comment_content)); 690 $cur->comment_ip = $rs->comment_author_IP; 691 $cur->comment_trackback = $rs->comment_type == 'trackback' ? 1 : 0; 692 $cur->comment_site = substr($this->cleanStr($rs->comment_author_url), 0, 255); 693 if ($cur->comment_site == '') { 694 $cur->comment_site = null; 695 } 696 697 if ($rs->comment_approved == 'spam') { 698 $cur->comment_status = -2; 699 } 700 701 $cur->comment_words = implode(' ', text::splitWords($cur->comment_content)); 702 703 $cur->comment_id = $this->con->select( 704 'SELECT MAX(comment_id) FROM ' . $this->prefix . 'comment' 705 )->f(0) + 1; 706 707 $cur->insert(); 708 709 if ($cur->comment_trackback && $cur->comment_status == 1) { 710 $count_t++; 711 } elseif ($cur->comment_status == 1) { 712 $count_c++; 713 } 714 } 715 716 if ($count_t > 0 || $count_c > 0) { 717 $this->con->execute( 718 'UPDATE ' . $this->prefix . 'post SET ' . 719 'nb_comment = ' . $count_c . ', ' . 720 'nb_trackback = ' . $count_t . ' ' . 721 'WHERE post_id = ' . (integer) $new_post_id . ' ' 722 ); 723 } 724 } 725 726 # Pings import 727 protected function importPings($post_id, $new_post_id, $db) 728 { 729 $urls = array(); 730 $pings = array(); 731 732 $rs = $db->select( 733 'SELECT pinged FROM ' . $this->vars['db_prefix'] . 'posts ' . 734 'WHERE ID = ' . (integer) $post_id 735 ); 736 $pings = explode("\n", $rs->pinged); 737 unset($pings[0]); 738 739 foreach ($pings as $ping_url) { 740 $url = $this->cleanStr($ping_url); 741 if (isset($urls[$url])) { 742 continue; 743 } 744 745 $cur = $this->con->openCursor($this->prefix . 'ping'); 746 $cur->post_id = (integer) $new_post_id; 747 $cur->ping_url = $url; 748 $cur->insert(); 749 750 $urls[$url] = true; 751 } 752 } 753 754 # Meta import 755 protected function importTags($post_id, $new_post_id, $db) 756 { 757 $rs = $db->select( 758 'SELECT * FROM ' . $this->vars['db_prefix'] . 'terms AS t, ' . 759 $this->vars['db_prefix'] . 'term_taxonomy AS x, ' . 760 $this->vars['db_prefix'] . 'term_relationships AS r ' . 761 'WHERE t.term_id = x.term_id ' . 762 'AND x.taxonomy = \'post_tag\' ' . 763 'AND t.term_id = r.term_taxonomy_id ' . 764 'AND r.object_id =' . $post_id . 765 ' ORDER BY t.term_id ASC' 766 ); 767 768 if ($rs->isEmpty()) { 769 return; 770 } 771 772 while ($rs->fetch()) { 773 $this->core->meta->setPostMeta($new_post_id, 'tag', $this->cleanStr($rs->name)); 774 } 775 } 800 776 }
Note: See TracChangeset
for help on using the changeset viewer.