| [ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file implements importing of Movable Type entries into b2evolution. 4 * 5 * {@internal 6 * TODO: 7 * - Wrap this by an abstract import class! 8 * - list of all posts, editable (overkill?) 9 * - assign comment_author_ID to comments if user exist?! }} 10 * 11 * 12 * This script was developed and tested with b2evolution 0.9.0.4 (on Sourceforge CVS) 13 * and Movable Type 2.64 and 2.661. 14 * It should work quite alright with b2evo 0.9 and later though. 15 * 16 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}. 17 * See also {@link http://sourceforge.net/projects/evocms/}. 18 * 19 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}. 20 * Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}. 21 * Credits go to the WordPress team (@link http://wordpress.org), where I got the basic 22 * import-mt.php script with most of the core functions. Thank you! 23 * 24 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL) 25 * 26 * {@internal Open Source relicensing agreement: 27 * Daniel HAHLER grants Francois PLANQUE the right to license 28 * Daniel HAHLER's contributions to this file and the b2evolution project 29 * under any OSI approved OSS license (http://www.opensource.org/licenses/). 30 * }} 31 * 32 * @package admin 33 * 34 * {@internal Below is a list of authors who have contributed to design/coding of this file: }} 35 * @author fplanque: Francois PLANQUE 36 * @author blueyed: Daniel HAHLER 37 * 38 * @version $Id: mtimport.ctrl.php,v 1.3 2007/10/09 01:18:12 fplanque Exp $ 39 */ 40 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 41 42 43 /** 44 * @const IMPORT_SRC_DIR directory where to be imported files get searched for. 45 */ 46 define('IMPORT_SRC_DIR', $basepath); 47 48 /** 49 * Enter the relative path of the import.txt file containing the MT entries. 50 * If the file is called import.txt and it is in /admin, then this line should be: 51 * <code> 52 * define('MTEXPORT', 'import.txt'); 53 * </code> 54 * 55 * You only need this to force a specific file instead of using a dropdown list 56 * (UI selection) 57 */ 58 define('MTEXPORT', ''); 59 60 /** 61 * Set to true to get a lot of var_dumps, wrapped in pre tags 62 */ 63 $output_debug_dump = 0; 64 65 66 // ----------- don't change below if you don't know what you do ------------------------ 67 // TODO: Make this AdminUI compliant, or better: make an MT import plugin.. 68 69 load_funcs('files/model/_file.funcs.php'); 70 load_class('items/model/_item.class.php'); 71 72 set_magic_quotes_runtime( 0 ); // be clear on this 73 74 // TODO: $io_charset !! 75 $head = <<<EOB 76 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 77 <html xmlns="http://www.w3.org/1999/xhtml"> 78 <head> 79 <title>b2evolution › Import from Movable Type</title> 80 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 81 <link href="{$adminskins_url}legacy/rsc/css/variation.css" rel="stylesheet" type="text/css" title="Variation" /> 82 <link href="{$adminskins_url}legacy/rsc/css/desert.css" rel="alternate stylesheet" type="text/css" title="Desert" /> 83 <link href="{$adminskins_url}legacy/rsc/css/legacy.css" rel="alternate stylesheet" type="text/css" title="Legacy" /> 84 EOB; 85 if( is_file( $adminskins_path.'legacy/rsc/css/custom.css' ) ) 86 { 87 $head .= '<link href="'.$adminskins_url.'legacy/rsc/css/custom.css" rel="alternate stylesheet" type="text/css" title="Custom" />'; 88 } 89 $head .= <<<EOB 90 <script type="text/javascript" src="{$rsc_url}js/styleswitcher.js?v=2"></script> 91 </head> 92 <body> 93 <div id="header"> 94 <div id="headinfo"> 95 <span style="font-size:150%; font-weight:bold">Movable Type to b2evolution importer</span> 96 [<a href="admin.php?ctrl=tools">Back to b2evolution</a>] 97 </div> 98 EOB; 99 100 $conf_file = $conf_path.'_config.php'; 101 if( !file_exists( $conf_file ) ) 102 { 103 dieerror( "There doesn't seem to be a conf/_config.php file. You must install b2evolution before you can import any entries.", $head ); 104 } 105 require( $conf_file ); 106 if( ! isset($config_is_done) || ! $config_is_done ) 107 { 108 $error_message = ''; 109 require( $inc_path.'_conf_error_page.php' ); 110 111 dieerror( 'b2evolution configuration is not done yet.', $head ); 112 } 113 114 115 // TODO: this should use no output buffering (probably to display page content during import, which may take long)! 116 117 118 // Check if user is logged in and is in group #1 (admins) 119 if( !is_logged_in() || $current_User->Group->ID != 1 ) 120 { // login failed 121 debug_die( 'You must login with an administrator (group #1) account.' ); 122 } 123 124 echo $head; 125 126 param( 'exportedfile', 'string', '' ); 127 param( 'import_mode', 'string', 'normal' ); 128 129 /*** mode-tabs ***/ ?> 130 <ul class="tabs"><?php 131 foreach( array( 'easy', 'normal', 'expert' ) as $tab ) 132 { 133 echo ( $tab == $import_mode ) ? '<li class="current">' : '<li>'; 134 echo '<a href="admin.php?ctrl=mtimport&import_mode='.$tab.( !empty($exportedfile) ? '&exportedfile='.$exportedfile : '' ).'">'.ucwords($tab).'</a></li>'; 135 } 136 ?></ul> 137 </div> 138 139 <div style="padding-top:1em;clear:both;"> 140 <?php 141 // check existence of export-file 142 if( empty($exportedfile) ) 143 { 144 if( '' != MTEXPORT && !file_exists(MTEXPORT) ) 145 { 146 ?> 147 <div class="error"><p> 148 The MT export file you defined in MTEXPORT at top of the script does not seem to exist. 149 Please check the path you've given for MTEXPORT or choose a file below. 150 </p></div> 151 <?php 152 } 153 elseif( '' != MTEXPORT ) 154 { 155 $exportedfile = MTEXPORT; 156 } 157 if( empty($exportedfile) ) 158 { // no valid MTEXPORT defined 159 chooseexportfile(); 160 echo '</div></div></body></html>'; 161 exit; 162 } 163 } 164 else 165 { 166 if( !file_exists($exportedfile) ) 167 { 168 chooseexportfile(); 169 dieerror("The MT export file [$exportedfile] you've chosen does not seem to exist. Please check path/permission."); 170 } 171 } 172 173 // get the params 174 param( 'simulate', 'integer', 0 ); 175 param( 'default_password', 'string', 'changeme' ); 176 param( 'default_password2', 'string', 'changeme' ); 177 param( 'post_locale', 'string', $Settings->get( 'default_locale' ) ); 178 179 if( $default_password != $default_password2 ) 180 { 181 dieerror( 'The two passwords for new users are not identical.' ); 182 } 183 184 param( 'default_userlevel', 'integer', 1 ); 185 if( $default_userlevel > 10 ) $default_userlevel = 10; 186 param( 'default_usergroup', 'integer', $Settings->get('newusers_grp_ID') ); 187 param( 'default_convert_breaks', 'integer', 1 ); 188 param( 'convert_html_tags', 'integer', 0 ); 189 190 param( 'action', 'string', '' ); 191 192 193 // global arrays 194 $categories_countprim = array(); // counts posts in primary categories 195 196 // load caches 197 blog_load_cache(); 198 cat_load_cache( 'none' ); 199 200 $i_user = -1; 201 202 if( empty($action) ) 203 { 204 param( 'import_mode', 'string', 'normal', true ); 205 import_data_extract_authors_cats(); 206 207 ?> 208 <div class="panelinfo"> 209 <p>We are about to import <?php 210 echo '['.$exportedfile.'].'; 211 if( '' == MTEXPORT ) 212 { 213 ?> [<a href="admin.php?ctrl=mtimport&import_mode=<?php echo $import_mode ?>">choose another export-file</a>]<?php 214 } ?></p> 215 216 <p>This file contains <?php echo count( $posts ) ?> post(s) from <?php echo count( $authors ) ?> author(s) in <?php echo count( $categories ) ?> category(ies).</p> 217 218 <p>We'll import into b2evolution's database "<?php echo $db_config['name'] ?>".</p> 219 </div> 220 <div class="panelinfo"> 221 <p>Before importing, you should check the URLs of any <img> tags you may have in <?php echo $exportedfile ?>. Will these URLs still be valid after the migration? If not, we advise you do a search and replace on <?php echo $exportedfile ?> before continuing.</p> 222 223 <p>Preferred location for inline images is the blog media folder.</p> 224 225 <p>You can also handle the images later, but it might be easier now :)</p> 226 </div> 227 228 <div class="panelinfo"> 229 <p>The importer is smart enough not to import duplicates, so you can run this procedure multiple times without worrying if — for whatever reason — it doesn't finish (script timeout for example).</p> 230 </div> 231 232 233 <div class="panelblock"> 234 <form class="fform" action="admin.php" method="post"> 235 <input type="hidden" name="ctrl" value="mtimport" /> 236 <input type="hidden" name="action" value="import" /> 237 <?php 238 if( !empty($exportedfile) ) 239 { 240 ?><input type="hidden" name="exportedfile" value="<?php echo format_to_output( $exportedfile, 'formvalue' ) ?>" /> 241 <?php 242 } 243 244 ?> 245 246 <?php 247 switch( $import_mode ) 248 { 249 case 'easy': 250 ?> 251 <h2>Easy Import:</h2> 252 <ul> 253 <li>MT users with no matching b2evolution user login will be automatically created.</li> 254 <li>MT categories with no matching b2evolution category name will be automatically created (in the default blog selected below.)</li> 255 <?php 256 if( isset($categories_countprim['[no category assigned]']) ) 257 { ?> 258 <li>Entries without categories (<?php echo $categories_countprim['[no category assigned]'] ?>) will be imported to category '[no category assigned]' in the default blog.</li> 259 <?php 260 } 261 echo '</ul>'; 262 break; 263 case 'normal': 264 ?> 265 <h2>Normal Import:</h2> 266 <ul> 267 <li>MT users can be mapped to existing b2evo users, mapped to new users (provide login) or ignored.</li> 268 <li>Categories can be mapped to existing b2evo categories, mapped to new categories (provide location + name) or ignored.</li> 269 </ul> 270 <?php 271 break; 272 case 'expert': 273 ?> 274 <h2>Expert Import:</h2> 275 <p>This gives you as much power as we can provide. It's like normal mode, but lets you map categories to a whole set of b2evo categories (one main category and as many extra categories as you like). You can run the importer multiple times to use different sets of b2evo categories for different sets of MT categories.</p> 276 <?php 277 break; 278 279 } 280 281 ?> 282 283 <?php if( $import_mode != 'expert' ) { ?> 284 <fieldset> 285 <legend>Default blog</legend> 286 <fieldset> 287 <div class="label"><?php echo ( $import_mode == 'easy' ) ? 'Create categories in blog' : 'Use as default blog for categories' ?>:</div> 288 <div class="input"> 289 <select name="default_blog"> 290 <?php 291 $BlogCache = & get_Cache( 'BlogCache' ); 292 echo $BlogCache->get_option_list( 2 ); // use first non-all blog as default 293 ?> 294 </select> 295 </div> 296 </fieldset> 297 </fieldset> 298 <?php } ?> 299 300 <?php if( $import_mode != 'easy' ) { ?> 301 <fieldset><legend>Author mapping</legend> 302 <?php 303 $evousers = $DB->get_results('SELECT * FROM T_users ORDER BY user_ID'); 304 foreach ($authors as $author) 305 { 306 ++$i_user; 307 ?> 308 <fieldset> 309 <div class="label"><label><?php echo $author ?></label></div> 310 <div class="input"> 311 <select name="user_select[]"> 312 <option value="#CREATENEW#" selected="selected"> Create new: </option> 313 <option value="#IGNORE#"> Ignore! </option> 314 <?php 315 foreach( $evousers as $user ) 316 { 317 ?><option value="<?php echo $user->user_ID ?>"<?php if( strtolower($author) == strtolower( $user->user_login ) ) echo ' selected="selected"'; 318 echo '>'.format_to_output(strtolower($user->user_login), 'formvalue').'</option>'; 319 } 320 ?></select> 321 <input type="text" value="<?php echo format_to_output($author, 'formvalue') ?>" name="user_name[]" maxlength="30" class="input" /> 322 <span class="notes">(login for new user)</span> 323 </div> 324 </fieldset> 325 <?php 326 } 327 ?> 328 </fieldset> 329 <?php } ?> 330 331 332 <fieldset><legend>New user defaults</legend> 333 <?php 334 form_text( 'default_password', $default_password, 20, 'Password for new users', 'this will be the password for users created during migration (default is "changeme")', 30 , '', 'password' ); 335 form_text( 'default_password2', $default_password, 20, 'Confirm password', 'please confirm the password', 30 , '', 'password' ); 336 $GroupCache = & get_Cache( 'GroupCache' ); 337 form_select_object( 'default_usergroup', $Settings->get('newusers_grp_ID'), $GroupCache, T_('User group') ); 338 $field_note = '[0 - 10] '.sprintf( T_('See <a %s>online manual</a> for details.'), 'href="http://manual.b2evolution.net/User_levels"' ); 339 form_text( 'default_userlevel', $Settings->get('newusers_level'), 2, T_('Level'), $field_note, 2 ); 340 ?> 341 </fieldset> 342 343 344 <?php if( $mode != 'easy' ){ ?> 345 <fieldset><legend>Category mapping</legend> 346 <?php 347 $i_cat = 0; 348 foreach( $categories as $cat ) 349 { 350 ?> 351 <fieldset> 352 <div class="label"> 353 <label><?php echo format_to_output($cat, 'htmlbody') ?></label> 354 <br /><span class="notes" style="font-weight:normal">used <?php echo @(int)$categories_countprim[$cat] ?> times as primary category</span> 355 </div> 356 <div class="input"><select name="catmap_select[]"> 357 <?php 358 if( $import_mode == 'expert' ) 359 echo '<option value="#DEFAULTSET#">Map to default categories set (see below)</option>'; 360 else echo '<option value="#DEFAULTBLOG#">Create in default blog:</option>'; ?> 361 <?php cats_optionslist( $cat ) ?> 362 <option value="#IGNORE#">Ignore entries with this primary cat</option> 363 </select> 364 <input type="text" name="catmap_name[]" value="<?php echo format_to_output( $cat, 'formvalue' ) ?>" size="30" /> 365 </div> 366 </fieldset> 367 <?php 368 $i_cat++; 369 } ?> 370 <?php 371 if( $import_mode == 'expert' ) 372 { 373 fieldset_cats(); 374 } 375 ?> 376 </fieldset> 377 <?php } ?> 378 379 380 <fieldset><legend>Post/Entry defaults</legend> 381 <?php 382 form_checkbox( 'default_convert_breaks', $default_convert_breaks, 'Convert-Breaks default', 'will be used for posts with empty CONVERT BREAKS or "__default__"' ); 383 form_select( 'post_locale', $Settings->get('default_locale'), 'locale_options', T_('Default locale'), 'Locale for posts.' ); 384 form_checkbox( 'convert_html_tags', $convert_html_tags, 'Convert ugly HTML', 'this will lowercase all html tags and add a XHTML compliant closing tag to <br>, <img>, <hr> (you\'ll get notes)' ); 385 386 if( $import_mode != 'easy' ) 387 { // we'll use 'default' when importing 388 ?> 389 <div class="label">Renderers:</div> 390 <div class="input"><?php renderer_list() ?></div> 391 <?php } ?> 392 </fieldset> 393 394 <?php /*<fieldset style="padding-left:1ex"><legend><img>-URL mapping</legend> 395 <a id="imgurls"><p class="notes">This lets you map found image urls (their basename) to another basename. 396 397 // TODO: refer to Blog media folder/url and ensure that it's enabled.. 398 399 You probably want to put the images that you had on your MT installation into b2evo's media folder.<br /> 400 So you would use <strong><?php echo "TODO" ?></strong> for replacement.<br /> 401 402 You can leave this empty, of course and nothing will be replaced, but then you'll have probably broken images.</p></a> 403 <?php 404 preg_match_all( '#<img .*?src="([^"]*)/.*?"#is', $importdata, $matches ); 405 406 foreach( $matches[1] as $imgurl ) 407 { 408 if( !isset($imgurlscount[ $imgurl ]) ) 409 $imgurlscount[ $imgurl ] = 1; 410 else $imgurlscount[ $imgurl ]++; 411 } 412 413 asort( $imgurlscount ); 414 $imgurlscount = array_reverse( $imgurlscount ); 415 416 param( 'singleimgurls', 'integer', 0 ); 417 $i = 0; 418 foreach( $imgurlscount as $imgurl => $counter ) if( $counter > 1 || $singleimgurls ) 419 { 420 ?><input type="hidden" name="url_search[<?php echo $i ?>]" value="<?php echo format_to_output( $imgurl, 'formvalue' ) ?>" /> 421 <strong><?php echo $imgurl ?></strong>:<br /> 422 <div class="input"><input style="clear:left" type="text" name="url_replace[]" size="50" /></div> 423 <span class="notes" style="font-weight:normal"> (used <?php echo $counter ?> times)</span> 424 <br /> 425 <?php 426 $i++; 427 } 428 429 echo '<p class="center"><a id="imgurls" href="admin.php?ctrl=mtimport&tab=import&singleimgurls='.( $singleimgurls ? '0' : '1' ); 430 if( !empty($exportedfile) ) echo '&exportedfile='.$exportedfile; 431 echo '">'.( $singleimgurls ? 'hide img urls only used once' : 'show also img urls only used once').'</a></p>'; 432 433 ?> 434 </fieldset> 435 */ ?> 436 437 <fieldset><legend>other settings</legend> 438 <?php 439 form_checkbox( 'simulate', $simulate, 'Simulate: do not import really', 'Use this to test importing, without really changing the target database.' ); 440 ?> 441 </fieldset> 442 <p>Please note:</p> 443 <ul> 444 <li>b2evolution does not support excerpts yet. 445 So, we will import them in front of the body with "<?php echo htmlspecialchars('<!--more-->< !--noteaser-->') ?>" tags, 446 but only if there is no extended body for the post. In that case we'll use the extended body appended with the <!--more--> tag to the body - excerpts are lost then (but you'll get a note about it). 447 </li> 448 </ul> 449 450 <fieldset class="submit"> 451 <div class="input"> 452 <input type="hidden" name="import_mode" value="<?php echo $import_mode ?>" /> 453 <input class="search" type="submit" value=" Import! " /> 454 <input class="search" type="reset" value="Reset form" /> 455 </div> 456 </fieldset> 457 458 </div> 459 460 </form> 461 462 <?php 463 } 464 465 466 /************* 467 IMPORT 468 *************/ 469 elseif( $action == 'import' ) 470 { 471 $Timer->start('import_main'); 472 ?> 473 <div class="panelinfo"> 474 <h4>Importing from [<?php echo $exportedfile ?>]..<?php if( $simulate ) echo ' (simulating)' ?></h4> 475 476 <?php 477 if( function_exists( 'set_time_limit' ) ) 478 { 479 set_time_limit( 900 ); // 15 minutes ought to be enough for everybody *g 480 } 481 @ini_set( 'max_execution_time', '900' ); 482 483 // counters 484 $count_postscreated = 0; 485 $count_userscreated = 0; 486 $count_commentscreated = 0; 487 $count_trackbackscreated = 0; 488 489 // get POSTed data 490 param( 'import_mode', 'string', true ); 491 492 if( $import_mode != 'expert' ) 493 { 494 param( 'default_blog', 'integer', true ); 495 } 496 497 import_data_extract_authors_cats(); 498 499 {{{ // map categories 500 /** 501 * associative array that maps MT cats to b2evo. 502 * key is the MT category name. 503 * values: 504 * holds type and value: 505 * types: 506 * - 'blogid': blog_id, new name 507 * - 'catid': cat_id 508 * - 'defaultset': - 509 * - 'ignore': - 510 */ 511 $catsmapped = array(); 512 513 $i_cat = -1; 514 // category mapping 515 if( !isset($_POST['catmap_select']) ) 516 { // no category mapping 517 foreach( $categories as $cat ) 518 { 519 $catsmapped[ $cat ] = array('blogid', $default_blog, $cat ); 520 } 521 } 522 else foreach( $_POST['catmap_select'] as $cat ) 523 { 524 $i_cat++; 525 if( $cat == '#IGNORE#' ) 526 { 527 $catsmapped[ $categories[$i_cat] ] = array( 'ignore' ); 528 } 529 elseif( $cat == '#DEFAULTSET#' ) 530 { 531 if( !isset( $default_post_category ) ) 532 { // get the default category set 533 if( isset($_POST['post_category']) ) 534 { 535 $default_post_category = (int)$_POST['post_category']; 536 } 537 else 538 { 539 dieerror( 'You have chosen to map at least one category to the default category set, but you have not selected a main category for this set!<br />Please go back and correct that..' ); 540 } 541 $default_post_extracats = array(); 542 if( isset( $_POST['post_extracats'] ) ) 543 { // get extra cats 544 foreach( $_POST['post_extracats'] as $tcat ) 545 { 546 $default_post_extracats[] = (int)$tcat; 547 } 548 } 549 } 550 $catsmapped[ $categories[$i_cat] ] = array( 'defaultset' ); 551 } 552 elseif( preg_match( '/^\d+$/', $cat, $match ) ) 553 { // we map to a b2evo cat 554 $catsmapped[ $categories[$i_cat] ] = array('catid', (int)$cat); 555 } 556 elseif( $cat == '#DEFAULTBLOG#' 557 || preg_match( '/^#NEW#(\d+)$/', $cat, $match ) ) 558 { // we want a new category 559 $blog_id = ($cat == '#DEFAULTBLOG#') ? $default_blog : $match[1]; 560 // remember the name to create it when posts get inserted 561 // fp>dh: please use param() instead of $_POST[] (everywhere) 562 $catsmapped[ $categories[$i_cat] ] = array( 'blogid', $blog_id, remove_magic_quotes( $_POST['catmap_name'][$i_cat]) ); 563 } 564 else 565 { 566 dieerror('This should never happen @catmapping. Please report it! (cat='.$cat.' / '); 567 } 568 569 } 570 571 foreach( $catsmapped as $mtcat => $values ) if( $values[0] == 'blogid' ) 572 { 573 echo 'Category <span style="color:#09c">'.$values[2].'</span> (for blog #'.$values[1].') '; 574 // check if it already exists 575 $cat_ID = $DB->get_var("SELECT cat_ID FROM T_categories 576 WHERE cat_blog_ID = {$values[1]} 577 AND cat_name = ".$DB->quote( $values[2] )); 578 if( !$cat_ID ) 579 { 580 echo 'will be created with first post.<br />'; 581 } 582 else 583 { 584 echo 'already exists.<br />'; 585 $catsmapped[ $mtcat ] = array('catid', (int)$cat_ID); // map to existing category 586 } 587 588 } 589 590 debug_dump( $catsmapped, 'catsmapped' ); 591 }}} 592 593 594 595 // get renderers 596 if( $import_mode != 'easy' ) 597 { 598 $default_renderers = array(); 599 if( !isset($_POST['renderers']) ) 600 { // all unchecked 601 $default_renderers = array(); 602 } 603 else $default_renderers = $_POST['renderers']; 604 605 // the special Auto-P renderer 606 param( 'autop', 'string', true ); 607 if( $autop === '1' ) 608 { // use always 609 $default_renderers[] = 'b2WPAutP'; 610 } 611 } 612 else 613 { 614 $Plugins_admin = & get_Cache('Plugins_admin'); 615 $default_renderers = $Plugins_admin->validate_renderer_list( array('default') ); 616 $autop = 1; 617 } 618 619 620 /* 621 // get image s&r 622 $urlsearch = array(); 623 $urlreplace = array(); 624 $i = 0; 625 foreach( $_POST['url_replace'] as $replace ) 626 { 627 if( !empty($replace) ) 628 { 629 $urlsearch[] = remove_magic_quotes($_POST['url_search'][$i]); 630 $urlreplace[] = remove_magic_quotes( $replace ); 631 } 632 $i++; 633 } 634 */ 635 636 // get users 637 $i_user = 0; 638 if( !isset($_POST['user_select']) ) 639 { 640 foreach( $authors as $author ) 641 { 642 $usersmapped[ $author ] = array('createnew', $author ); 643 } 644 645 } 646 else foreach( $_POST['user_select'] as $select ) 647 { 648 $mtauthor = $authors[ $i_user ]; 649 650 if( $select == '#IGNORE#' ) 651 { 652 $usersmapped[ $mtauthor ] = array( 'ignore' ); 653 } 654 elseif( $select == '#CREATENEW#' ) 655 { 656 $usersmapped[ $mtauthor ] = array( 'createnew', remove_magic_quotes( $_POST['user_name'][$i_user] ) ); 657 } 658 elseif( preg_match( '#\d+#', $select, $match ) ) 659 { 660 $usersmapped[ $mtauthor ] = array( 'b2evo', $select ); 661 } 662 else 663 { 664 ?><p class="error">Unknown user mapping. This should never ever happen. Please report it.</p><?php 665 } 666 $i_user++; 667 } 668 debug_dump( $usersmapped, 'usersmapped' ); 669 670 671 if( $simulate ) 672 { 673 $simulate_cat_id = $DB->get_var( 'SELECT MAX( cat_ID )+1 FROM T_categories' ); 674 } 675 676 $i = -1; 677 echo "\n<ol>"; 678 foreach ($posts as $post) 679 { 680 ++$i; 681 682 // Defaults: 683 $post_catids = array(); 684 $post_renderers = $default_renderers; 685 $post_status = 'published'; 686 687 // strip the post's last '--------' 688 // "MT export files use 8 dashes to delimit entires (not 5, which delimit entry's sections)." 689 $post = preg_replace("|--------\n+$|s", '', $post); 690 691 // first line is author of post 692 $post_author = trim( substr( $post, 0, strpos( $post, "\n", 1 ) ) ); 693 $post = preg_replace( '/^.*\n/', '', $post ); 694 $message = "\n<li>Post from ".format_to_output( $post_author, 'entityencoded' ).' <ul>'; 695 696 // Take the pings out first 697 preg_match("|(-----\n\nPING:.*)|s", $post, $pings); 698 $post = preg_replace("|(-----\n\nPING:.*)|s", '', $post); 699 700 // Then take the comments out 701 preg_match("|(-----\nCOMMENT:.*)|s", $post, $comments); 702 $post = preg_replace("|(-----\nCOMMENT:.*)|s", '', $post); 703 704 // We ignore the keywords 705 $post = preg_replace("|(-----\nKEYWORDS:.*)|s", '', $post); 706 707 // We want the excerpt - it's put with more and noteaser tag into main body, only if we have no extended body! 708 preg_match("|-----\nEXCERPT:(.*)|s", $post, $excerpt); 709 $excerpt = trim($excerpt[1]); 710 $post = preg_replace("|(-----\nEXCERPT:.*)|s", '', $post); 711 712 // We're going to put extended body into main body with a more tag 713 preg_match("|-----\nEXTENDED BODY:(.*)|s", $post, $extended); 714 $extended = trim($extended[1]); 715 $post = preg_replace("|(-----\nEXTENDED BODY:.*)|s", '', $post); 716 717 // Now for the main body 718 preg_match("|-----\nBODY:(.*)|s", $post, $body); 719 $body = trim($body[1]); 720 if( empty($extended) ) 721 { // no extended body, so we can use the excerpt 722 if( empty($excerpt) ) 723 $post_content = $body; 724 else $post_content = $excerpt."\n<!--more--><!--noteaser-->\n".$body; 725 } 726 else 727 { // we'll use body and extended body 728 if( !empty($excerpt) ) 729 { 730 $message .= '<li><span style="color:red">Excerpt discarded because of existing extended body:</span> 731 <blockquote>'.htmlspecialchars($excerpt).'</blockquote></li>'; 732 } 733 $post_content = $body."\n<!--more-->\n".$extended; 734 } 735 736 $post = preg_replace("|(-----\nBODY:.*)|s", '', $post); 737 738 739 // Grab the metadata from what's left 740 $metadata = explode("\n", $post); 741 742 $post_categories = array(); 743 foreach ($metadata as $line) if( !empty($line) ) 744 { 745 debug_dump($line); 746 747 if( !preg_match("/^(.*?):(.*)/", $line, $token) ) 748 { 749 $message .= "<li class=\"notes\">Unknown meta-data: [$line] (ignoring)</li>"; 750 continue; 751 } 752 $key = trim( $token[1] ); 753 $value = trim( $token[2] ); 754 755 // Now we decide what it is and what to do with it 756 switch($key) 757 { 758 case 'TITLE': 759 $message .= '<li>title: '.strip_tags($value).'</li>'; 760 $post_title = $value; 761 break; 762 case 'STATUS': 763 if( strtolower($value) == 'publish' ) 764 $post_status = 'published'; 765 elseif( strtolower($value) == 'draft' ) 766 $post_status = 'draft'; 767 else 768 { 769 $message .= '<li>Unknown post status ['.$value.'], using "draft".</li>'; 770 $post_status = 'draft'; 771 } 772 break; 773 case 'ALLOW COMMENTS': 774 $post_allow_comments = $value; 775 switch( $post_allow_comments ) { 776 case 0: $comment_status = 'disabled'; break; 777 case 1: $comment_status = 'open'; break; 778 case 2: $comment_status = 'closed'; break; 779 default: 780 $message .= '<li>Unknown comment status ['.$value.'], using "closed".</li>'; 781 $comment_status = 'closed'; 782 } 783 break; 784 case 'CONVERT BREAKS': 785 if( $value == '__default__' || empty($value) ) 786 { 787 $post_convert_breaks = $default_convert_breaks; 788 } 789 elseif( $value == 'textile_2' && array_search( 'b2DATxtl', $post_renderers ) === false ) 790 { // add the textile 2 renderer to the post's renderers 791 $post_renderers[] = 'b2DATxtl'; 792 $post_convert_breaks = 1; // TODO: check if this makes sense! 793 } 794 elseif( preg_match('/\d+/', $value) ) 795 { 796 $post_convert_breaks = (int)( $value > 0 ); 797 } 798 else 799 { 800 $message .= '<li>Unknown CONVERT BREAKS value, using default ('.$default_convert_breaks.')..</li>'; 801 $post_convert_breaks = $default_convert_breaks; 802 } 803 804 if( $autop == 'depends' && $post_convert_breaks && array_search( 'b2WPAutP', $post_renderers ) === false ) 805 { // add the Auto-P renderer 806 $post_renderers[] = 'b2WPAutP'; 807 } 808 809 break; 810 case 'ALLOW PINGS': 811 if( $value == 1) 812 { 813 $post_allow_pings = 'open'; 814 } 815 else 816 { 817 $post_allow_pings = 'closed'; 818 } 819 break; 820 case 'PRIMARY CATEGORY': 821 case 'CATEGORY': 822 if( !empty($value) && !isset($post_categories[$value]) ) 823 { 824 if( $catsmapped[ $value ][0] == 'defaultset' ) 825 { // we add default set 826 $post_categories[$value] = $default_post_extracats; 827 array_unshift( $post_categories[$value], 'catid', $default_post_category ); 828 } 829 else $post_categories[$value] = $catsmapped[ $value ]; 830 } 831 break; 832 case 'DATE': 833 $post_date = strtotime( $value ); 834 $post_date = date('Y-m-d H:i:s', $post_date); 835 break; 836 default: 837 $message .= "\n<li>Unknown key [$key] in metadata:\nvalue: $value\n</li>"; 838 break; 839 } 840 } // End foreach (metadata) 841 842 $dontimport = 0; 843 844 845 if( empty($post_categories) ) 846 { // no category metadata found! 847 848 if( $catsmapped[ '[no category assigned]' ][0] == 'defaultset' ) 849 { // we must convert default set 850 $post_categories['[no category assigned]'] = $default_post_extracats; 851 array_unshift( $post_categories['[no category assigned]'], 'catid', $default_post_category ); 852 } 853 else $post_categories[ '[no category assigned]' ] = $catsmapped[ '[no category assigned]' ]; 854 855 } 856 857 // Let's check to see if it's in already 858 if( $post_ID = $DB->get_var( "SELECT post_ID 859 FROM T_items__item 860 WHERE post_title = ".$DB->quote($post_title)." 861 AND post_datestart = '$post_date'")) 862 { 863 $message .= '<li style="color:blue">Post already imported.</li>'; 864 } 865 else 866 { // insert post 867 868 // check&map author 869 switch( $usersmapped[ $post_author ][0] ) 870 { 871 case 'ignore': 872 $message .= '<li style="color:blue">User ignored!</li>'; 873 echo $message.'</ul>'; 874 continue; // next post 875 876 case 'b2evo': 877 $item_Author = & $UserCache->get_by_login( $usersmapped[ $post_author ][1] ); 878 break; 879 880 case 'createnew': 881 // check if the user already exists 882 $UserCache = & get_Cache( 'UserCache' ); 883 $item_Author = & $UserCache->get_by_login( $usersmapped[ $post_author ][1] ); 884 885 if( ! $item_Author ) 886 { 887 $item_Author = new User(); 888 $item_Author->set('login', strtolower($usersmapped[ $post_author ][1])); 889 $item_Author->set('nickname', $usersmapped[ $post_author ][1]); 890 $item_Author->set('pass', md5( $default_password )); 891 $item_Author->set('level', $default_userlevel); 892 $item_Author->set('email', ''); 893 $GroupCache = & get_Cache( 'GroupCache' ); 894 $item_Author_Group = & $GroupCache->get_by_ID( $default_usergroup ); 895 $item_Author->set_Group( $item_Author_Group ); 896 897 if( !$simulate ) 898 { 899 $item_Author->dbinsert(); 900 } 901 902 // This is a bad hack, because add() would need an ID (which we don't have when simulating) 903 $UserCache->cache_login[ $item_Author->login ] = & $item_Author; 904 905 $message .= '<li style="color:orange">user '.$item_Author->login.' created</li>'; 906 $count_userscreated++; 907 } 908 break; 909 default: 910 $message .= '<li style="color:red">unknown type in checkauthor ('.$usersmapped[ $author ][0].'). This should never ever happen. Post ignored. Please report it.</li>'; 911 echo $message.'</ul>'; 912 continue; // next post 913 } 914 915 916 debug_dump( $post_categories, 'cats to check' ); 917 918 // Check categories 919 $i_cat = -1; 920 $message_ignored = ''; 921 foreach( $post_categories as $catname => $checkcat ) 922 { 923 $i_cat++; 924 switch( $checkcat[0] ) 925 { 926 case 'catid': // existing b2evo catids 927 array_shift($checkcat); 928 while( $cat_id = array_shift($checkcat) ) 929 $post_catids[] = $cat_id; // get all catids 930 continue; 931 932 case 'ignore': // category is ignored 933 if( $i_cat == 0 ) 934 { // main category ignored, don't import post 935 $dontimport = 1; 936 $message_ignored .= '<li>Main Category "'.$catname.'" ignored! - no import</li>'; 937 break; 938 } 939 else 940 { // ignored category in extracats, remove it there 941 $message_ignored .= '<li>Extra category '.$catname.' ignored.</li>'; 942 unset( $post_categories[ $catname ] ); 943 } 944 break; 945 946 case 'blogid': // category has to be created 947 // create it and remember ID 948 if( $simulate ) 949 { 950 $cat_id = ++$simulate_cat_id; 951 } 952 else 953 { 954 $cat_id = cat_create( $checkcat[2], 'NULL', $checkcat[1] ); 955 } 956 $catsmapped[ $catname ] = array( 'catid', $cat_id ); // use ID from now on. 957 958 if( !isset($cache_categories[ $cat_id ] ) ) 959 { // stupid workaround because of a bug where cache_categories does not get updated and we want to use get_catname later 960 $cache_categories[ $cat_id ] = array( 961 'cat_name' => $checkcat[2], 962 'cat_blog_ID' => $checkcat[1], 963 'cat_parent_ID' => NULL, 964 'cat_postcount' => 0, 965 'cat_children' => 0 966 ); 967 } 968 $post_catids[] = $cat_id; 969 $message .= '<li style="color:orange">category '.$checkcat[2].' [ID '.$cat_id.'] created</li>'; 970 break; 971 972 default: 973 $message .= '<li style="color:red">This should never ever happen @check_cats. Please report it! (checkcat[0]: '.$checkcat[0].')</li>'; 974 975 } 976 } 977 if( !empty($message_ignored) ) 978 $message .= '<li style="color:blue">Categories ignored: <ul>'.$message_ignored.'</ul></li>'; 979 980 debug_dump( $dontimport, 'dontimport' ); 981 if( $dontimport ) 982 { // see var name :) 983 echo $message; 984 continue; // next post 985 } 986 987 if( $convert_html_tags ) 988 { 989 $old_content = $post_content; 990 // convert tags to lowercase 991 $post_content = stripslashes( preg_replace( "¤(</?)(\w+)([^>]*>)¤e", "'\\1'.strtolower('\\2').'\\3'", $post_content ) ); 992 993 // close br, hr and img tags 994 $post_content = preg_replace( array('¤<(br)>¤', '¤<(hr\s?.*?)>¤', '¤<(img\s.*?)>¤'), '<\\1 />', $post_content ); 995 996 997 // add quotes for href tags that don't have them 998 $post_content = preg_replace( '¤href=([^"\'][^\s>"\']+)["\']?¤', 'href="$1"', $post_content ); 999 1000 if( $post_content != $old_content ) 1001 { 1002 $message .= '<li><p style="color:darkblue;border:1px dashed orange;">'.htmlspecialchars($old_content).'</p> 1003 html-converted to: <p style="color:darkblue;border:1px dashed orange;">'.htmlspecialchars($post_content).'</p></li>'; 1004 } 1005 } 1006 1007 /*if( count($urlreplace) ) 1008 { 1009 $old_content = $post_content; 1010 foreach( $urlreplace as $search => $replace ) 1011 { 1012 $post_content = str_replace( $urlsearch, $urlreplace, $post_content ); 1013 } 1014 if( $post_content != $old_content ) 1015 { 1016 echo '<p style="color:darkblue;border:1px dashed orange;">'.htmlspecialchars($old_content).'</p> 1017 converted img-links to: <p style="color:darkblue;border:1px dashed orange;">'.htmlspecialchars($post_content).'</p>'; 1018 } 1019 }*/ 1020 1021 debug_dump( $post_catids, 'post_extracats' ); 1022 $post_category = array_shift($post_catids); 1023 debug_dump( $post_category, 'post_category' ); 1024 debug_dump( $post_categories, 'post_categories' ); 1025 debug_dump( $post_author, 'post_author' ); 1026 debug_dump( isset($item_Author->ID) ? $item_Author->ID : 'NULL (simulating)', 'item_Author->ID' ); 1027 1028 if( !$simulate ) 1029 { 1030 $edited_Item = & new Item(); 1031 $edited_Item->set_creator_User($item_Author); 1032 $edited_Item->set('title', $post_title); 1033 $edited_Item->set('content', $post_content); 1034 $edited_Item->set('datestart', $post_date); 1035 $edited_Item->set('main_cat_ID', $post_category); 1036 $edited_Item->set('extra_cat_IDs', $post_catids); 1037 $edited_Item->set('status', $post_status); 1038 $edited_Item->set('locale', $post_locale); 1039 $edited_Item->set('notifications_status', 'finished'); 1040 $edited_Item->set('comment_status', $comment_status); 1041 $edited_Item->set_renderers($post_renderers); 1042 $edited_Item->dbinsert(); 1043 $post_ID = $edited_Item->ID; 1044 } 1045 1046 $message .= '<li><span style="color:green">Imported successfully</span><ul><li>main category: <span style="color:#09c">'.get_catname( $post_category ).'</span></li>'; 1047 if( count($post_catids) ) 1048 $message .= '<li>extra categories: <span style="color:#09c">'.preg_replace( '/(\d+)/e', "get_catname('\\1')", implode( ', ', $post_catids ) ).'</span></li>'; 1049 $message .= '</ul></li>'; 1050 $count_postscreated++; 1051 1052 } 1053 echo $message.'</ul>'; 1054 1055 1056 if( count($comments) ) 1057 { // comments 1058 $message = ''; 1059 1060 $comments = explode("-----\nCOMMENT:", $comments[0]); 1061 foreach ($comments as $comment) 1062 { 1063 $comment = trim($comment); 1064 if( empty($comment) ) continue; 1065 1066 $comment_author = ripline( 'AUTHOR:', $comment ); 1067 $comment_email = ripline( 'EMAIL:', $comment ); 1068 $comment_ip = ripline( 'IP:', $comment ); 1069 $comment_url = ripline( 'URL:', $comment ); 1070 $comment_date = date('Y-m-d H:i:s', strtotime( ripline( 'DATE:', $comment ))); 1071 1072 $comment_content = preg_replace("/\n*-----$/", '', $comment); 1073 1074 // Check if it's already in there 1075 if( !$DB->get_row("SELECT * FROM T_comments WHERE comment_date = '$comment_date' AND comment_content = ".$DB->quote( $comment_content )) ) 1076 { 1077 if( !$simulate ) 1078 { 1079 $DB->query( "INSERT INTO T_comments( comment_post_ID, comment_type, comment_author_ID, comment_author, 1080 comment_author_email, comment_author_url, comment_author_IP, 1081 comment_date, comment_content) 1082 VALUES( $post_ID, 'comment', NULL, ".$DB->quote($comment_author).", 1083 ".$DB->quote($comment_email).", ".$DB->quote($comment_url).", 1084 ".$DB->quote($comment_ip).", '$comment_date', ".$DB->quote($comment_content)." )" ); 1085 } 1086 1087 $message .= '<li>Comment from '.$comment_author.' added.</li>'; 1088 $count_commentscreated++; 1089 } 1090 } 1091 if( !empty($message) ) 1092 { 1093 echo '<ul>'.$message.'</ul>'; 1094 } 1095 1096 } 1097 1098 // Finally the pings 1099 // fix the double newline on the first one 1100 if( count($pings) ) 1101 { 1102 $message = ''; 1103 $pings[0] = str_replace("-----\n\n", "-----\n", $pings[0]); 1104 $pings = explode("-----\nPING:", $pings[0]); 1105 foreach( $pings as $ping ) 1106 { 1107 $ping = trim($ping); 1108 if( empty($ping) ) continue; 1109 1110 $comment_author = ripline( 'BLOG NAME:', $ping ); 1111 $comment_email = ''; 1112 $comment_ip = ripline( 'IP:', $ping ); 1113 $comment_url = ripline( 'URL:', $ping ); 1114 $comment_date = date('Y-m-d H:i:s', strtotime( ripline( 'DATE:', $ping ))); 1115 $ping_title = ripline( 'TITLE:', $ping ); 1116 1117 $comment_content = preg_replace("/\n*-----$/", '', $ping); 1118 1119 $comment_content = "<strong>$ping_title</strong><br />$comment_content"; 1120 1121 // Check if it's already there 1122 if (!$DB->get_row("SELECT * FROM T_comments WHERE comment_date = '$comment_date' AND comment_type = 'trackback' AND comment_content = ".$DB->quote($comment_content))) 1123 { 1124 if( !$simulate ) 1125 { 1126 $DB->query( "INSERT INTO T_comments 1127 (comment_post_ID, comment_type, comment_author, comment_author_email, comment_author_url, 1128 comment_author_IP, comment_date, comment_content ) 1129 VALUES 1130 ($post_ID, 'trackback', ".$DB->quote($comment_author).", ".$DB->quote($comment_email).", ".$DB->quote($comment_url).", 1131 ".$DB->quote($comment_ip).", ".$DB->quote($comment_date).", ".$DB->quote($comment_content)." )" ); 1132 } 1133 $message .= '<li>Trackback from '.$comment_url.' added.</li>'; 1134 $count_trackbackscreated++; 1135 } 1136 } 1137 echo $message; 1138 } 1139 1140 echo "</li>\n"; 1141 flush(); 1142 } 1143 ?> 1144 </ol> 1145 <h4>All done.<?php if( $simulate ) echo ' (simulated - no real import!)' ?></h4> 1146 <ul> 1147 <li><?php echo $count_postscreated ?> post(s) imported.</li> 1148 <li><?php echo $count_userscreated ?> user(s) created.</li> 1149 <li><?php echo $count_commentscreated ?> comment(s) imported.</li> 1150 <li><?php echo $count_trackbackscreated ?> trackback(s) imported.</li> 1151 <li>in <?php echo $Timer->get_duration('import_main') ?> seconds.</li> 1152 </ul> 1153 <?php 1154 if( $simulate ) 1155 { 1156 echo ' 1157 <form action="admin.php" method="post"> 1158 <input type="hidden" name="ctrl" value="mtimport" /> 1159 <p> 1160 <strong>This was only simulated..</strong> 1161 '; 1162 foreach( $_POST as $key => $value ) 1163 { 1164 if( $key != 'simulate' ) 1165 { 1166 if( is_array( $value ) ) 1167 { 1168 foreach( $value as $key2 => $value2 ) 1169 { 1170 echo '<input type="hidden" name="'.$key.'['.$key2.']" value="'.format_to_output( $value2, 'formvalue' ).'" />'; 1171 } 1172 } 1173 else 1174 { 1175 echo '<input type="hidden" name="'.$key.'" value="'.format_to_output( $value, 'formvalue' ).'" />'; 1176 } 1177 } 1178 } 1179 echo '<input type="submit" value="Do it for real now!" /></p></form>'."\n"; 1180 } 1181 ?> 1182 <p> 1183 <a href="<?php echo $baseurl ?>">Have fun in your blogs</a> or <a href="<?php echo $admin_url ?>">go to admin</a> (it's fun there, too) 1184 </p> 1185 <?php 1186 if( $count_userscreated ) 1187 { 1188 echo '<p class="note">Please note that the new users being created are not member of any blog yet. You\'ll have to setup this in the <a href="'.$admin_url.'?ctrl=collections">blogs admin</a>.</p>'; 1189 } 1190 ?> 1191 </div> 1192 <?php 1193 } 1194 1195 ?> 1196 <div class="panelinfo"> 1197 <p> 1198 Feel free to <a href="http://thequod.de/contact">contact me</a> in case of suggestions, bugs and lack of clarity. 1199 Of course, you're also welcome to <a href="https://sourceforge.net/donate/index.php?user_id=663176">donate to me</a> or <a href="http://b2evolution.net/dev/donations.php">the b2evolution project</a>.. :) 1200 </p> 1201 </div> 1202 <div class="clear"> 1203 <?php if( $output_debug_dump ) $DB->dump_queries() ?> 1204 </div> 1205 </div> 1206 </body> 1207 </html> 1208 <?php 1209 1210 /* ------ FUNCTIONS ------ */ 1211 1212 /** 1213 * @todo fp> this needs to be deprecated 1214 * @todo fp> get rid of the $cache_blogs crap and use $BlogCache only 1215 */ 1216 function blog_load_cache() 1217 { 1218 global $DB, $cache_blogs; 1219 if( empty($cache_blogs) ) 1220 { 1221 $BlogCache = & get_Cache('BlogCache'); 1222 $cache_blogs = array(); 1223 1224 foreach( $DB->get_results( "SELECT * FROM T_blogs ORDER BY blog_ID", OBJECT, 'blog_load_cache()' ) as $this_blog ) 1225 { 1226 $cache_blogs[$this_blog->blog_ID] = $this_blog; 1227 1228 // Add it to BlogCache, so it does not need to load it also again: 1229 // NOTE: dh> it may be bad to instantiate all objects, but there's no shadow_cache for rows.. 1230 $BlogCache->instantiate($this_blog); 1231 //echo 'just cached:'.$cache_blogs[$this_blog->blog_ID]->blog_name.'('.$this_blog->blog_ID.')<br />'; 1232 } 1233 $BlogCache->all_loaded = true; 1234 } 1235 } 1236 1237 1238 /** 1239 * Get name for a given cat 1240 */ 1241 function get_catname($cat_ID) 1242 { 1243 $cat = get_the_category_by_ID( $cat_ID ); 1244 return $cat['cat_name']; 1245 } 1246 1247 1248 function fieldset_cats() 1249 { 1250 global $cache_blogs, $cache_categories; 1251 1252 ?> 1253 <fieldset title="default categories set" style="background-color:#fafafa; border:1px solid #ccc; padding: 1em; display:inline; float:right; white-space:nowrap;"> 1254 <legend>Default categories set (only needed if you want to map categories to this)</legend> 1255 <p class="extracatnote"> 1256 <?php 1257 if( count( $cache_categories ) ) 1258 { 1259 echo T_('Select main category in target blog and optionally check additional categories').':'; 1260 } 1261 else 1262 { 1263 echo 'No categories in your blogs..'; 1264 } 1265 ?> 1266 </p> 1267 1268 <?php 1269 // ---------------------------- CATEGORIES ------------------------------ 1270 $default_main_cat = 0; 1271 $blog = 1; 1272 1273 // ----------------- START RECURSIVE CAT LIST ---------------- 1274 cat_load_cache(); // make sure the caches are loaded 1275 function import_cat_select_before_first( $parent_cat_ID, $level ) 1276 { // callback to start sublist 1277 echo "\n<ul>\n"; 1278 } 1279 1280 function import_cat_select_before_each( $cat_ID, $level ) 1281 { // callback to display sublist element 1282 global $current_blog_ID, $blog, $cat, $postdata, $default_main_cat, $action, $tabindex, $allow_cross_posting; 1283 $this_cat = get_the_category_by_ID( $cat_ID ); 1284 echo '<li>'; 1285 1286 if( $allow_cross_posting ) 1287 { // We allow cross posting, display checkbox: 1288 echo'<input type="checkbox" name="post_extracats[]" class="checkbox" title="', T_('Select as an additionnal category') , '" value="',$cat_ID,'"'; 1289 echo ' />'; 1290 } 1291 1292 // Radio for main cat: 1293 if( $current_blog_ID == $blog ) 1294 { 1295 if( ($default_main_cat == 0) && ($action == 'post') ) 1296 { // Assign default cat for new post 1297 $default_main_cat = $cat_ID; 1298 } 1299 echo ' <input type="radio" name="post_category" class="checkbox" title="', T_('Select as MAIN category'), '" value="',$cat_ID,'"'; 1300 if( ($cat_ID == $postdata["Category"]) || ($cat_ID == $default_main_cat)) 1301 echo ' checked="checked"'; 1302 echo ' />'; 1303 } 1304 echo ' '.$this_cat['cat_name']; 1305 } 1306 1307 function import_cat_select_after_each( $cat_ID, $level ) 1308 { // callback after each sublist element 1309 echo "</li>\n"; 1310 } 1311 1312 function import_cat_select_after_last( $parent_cat_ID, $level ) 1313 { // callback to end sublist 1314 echo "</ul>\n"; 1315 } 1316 1317 // go through all blogs with cats: 1318 foreach( $cache_blogs as $i_blog ) 1319 { // run recursively through the cats 1320 $current_blog_ID = $i_blog->blog_ID; 1321 if( ! blog_has_cats( $current_blog_ID ) ) continue; 1322 #if( ! $current_User->check_perm( 'blog_post_statuses', 'any', false, $current_blog_ID ) ) continue; 1323 echo "<h4>".$i_blog->blog_name."</h4>\n"; 1324 cat_children( $cache_categories, $current_blog_ID, NULL, 'import_cat_select_before_first', 1325 'import_cat_select_before_each', 'import_cat_select_after_each', 'import_cat_select_after_last', 1 ); 1326 } 1327 // ----------------- END RECURSIVE CAT LIST ---------------- 1328 ?> 1329 </fieldset> 1330 <?php 1331 } 1332 1333 1334 /* 1335 -- Category options list -- 1336 */ 1337 function cats_optionslist( $forcat ) 1338 { 1339 global $cache_categories, $cache_blogs, $cache_optionslist; 1340 1341 if( !isset($cache_optionslist) ) 1342 { 1343 $cache_optionslist = ''; 1344 foreach( $cache_blogs as $i_blog ) 1345 { 1346 $cache_optionslist .= '<option value="#NEW#'.$i_blog->blog_ID.'">[-- create in blog '.$i_blog->blog_shortname.' --]:</option>'; 1347 cat_children2( $cache_categories, $i_blog->blog_ID, NULL, 1 ); 1348 } 1349 } 1350 1351 $cat_id = false; 1352 foreach( $cache_categories as $key => $value ) 1353 { 1354 if( $value['cat_name'] == $forcat ) 1355 { 1356 $cat_id = $key; 1357 break; 1358 } 1359 } 1360 1361 if( is_int($cat_id) ) 1362 { 1363 echo str_replace( '<option value="'.$cat_id.'">', '<option value="'.$cat_id.'" selected="selected">', $cache_optionslist ); 1364 } 1365 else 1366 { 1367 echo $cache_optionslist; 1368 } 1369 } 1370 1371 function cat_children2( 1372 $ccats, // PHP requires this stupid cloning of the cache_categories array in order to be able to perform foreach on it 1373 $blog_ID, 1374 $parent_ID, 1375 $level = 0 ) // Caller nesting level, just to keep track of how far we go :) 1376 { 1377 global $cache_optionslist; 1378 1379 // echo 'Number of cats=', count($ccats); 1380 if( ! empty( $ccats ) ) // this can happen if there are no cats at all! 1381 { 1382 $child_count = 0; 1383 foreach( $ccats as $icat_ID => $i_cat ) 1384 { 1385 // fp> TODO: check what ($blog_ID == 0) is for .. ? 1386 if( $icat_ID 1387 && ( ($blog_ID == 0) || ($i_cat['cat_blog_ID'] == $blog_ID)) 1388 && ($i_cat['cat_parent_ID'] == $parent_ID) ) 1389 { // this cat is in the blog and is a child of the parent 1390 $child_count++; 1391 1392 $cache_optionslist .= '<option value="'.$icat_ID.'">'; 1393 1394 for( $i = 0; $i < $level; $i++ ) 1395 { 1396 $cache_optionslist .= '-'; 1397 } 1398 1399 $cache_optionslist .= '> '.format_to_output( $ccats[ $icat_ID ]['cat_name'], 'entityencoded' ).'</option>'; 1400 1401 cat_children2( $ccats, $blog_ID, $icat_ID, $level+1 ); 1402 } 1403 } 1404 } 1405 } 1406 1407 1408 /** 1409 * extracts unique authors and cats from posts array 1410 */ 1411 function import_data_extract_authors_cats() 1412 { 1413 global $authors, $categories, $posts; 1414 global $exportedfile; 1415 global $categories_countprim; 1416 global $importdata; 1417 global $import_mode; 1418 1419 $fp = fopen( $exportedfile, 'rb'); 1420 $buffer = fread($fp, filesize( $exportedfile )); 1421 fclose($fp); 1422 if( !preg_match( '/^[-\s]*AUTHOR: /', $buffer ) ) 1423 { 1424 dieerror("The file [$exportedfile] does not seem to be a MT exported file.. ".'[<a href="admin.php?ctrl=mtimport&import_mode='.$import_mode.'">choose another export-file</a>]'); 1425 } 1426 1427 $importdata = preg_replace( "/\r?\n|\r/", "\n", $buffer ); 1428 $posts = preg_split( '/(^|--------\n)(AUTHOR: |$)/', $importdata ); 1429 1430 $authors = array(); $tempauthors = array(); 1431 $categories = array(); $tempcategories = array(); 1432 1433 foreach ($posts as $nr => $post) 1434 { 1435 if ('' != trim($post)) 1436 { 1437 // first line is author of post 1438 $tempauthors[] = trim( substr( $post, 0, strpos( $post, "\n", 1 ) ) ); 1439 1440 $oldcatcount = count( $tempcategories ); 1441 1442 if( preg_match_all( "/^(PRIMARY )?CATEGORY: (.*)/m", $post, $matches ) ) 1443 { 1444 for( $i = 1; $i < count( $matches[2] ); $i++ ) 1445 { 1446 $cat = trim( $matches[2][$i] ); 1447 if( !empty( $cat ) ) $tempcategories[] = $cat; 1448 } 1449 1450 // main category last (-> counter) 1451 if( !empty($matches[2][0]) ) $tempcategories[] = $matches[2][0]; 1452 } 1453 1454 if( $oldcatcount == count( $tempcategories ) ) 1455 { 1456 $tempcategories[] = '[no category assigned]'; 1457 } 1458 1459 // remember how many times used as primary category 1460 @$categories_countprim[ $tempcategories[ count( $tempcategories )-1 ] ]++; 1461 } 1462 else 1463 { 1464 unset( $posts[ $nr ] ); 1465 } 1466 } 1467 1468 // we need to find unique values of author names, while preserving the order, so this function emulates the unique_value(); php function, without the sorting. 1469 $authors[0] = array_shift($tempauthors); 1470 $y = count($tempauthors) + 1; 1471 for ($x = 1; $x < $y; $x++) 1472 { 1473 $next = array_shift($tempauthors); 1474 if( !(in_array($next,$authors)) ) $authors[] = $next; 1475 } 1476 $categories[0] = array_shift( $tempcategories ); 1477 $y = count($tempcategories) + 1; 1478 for ($x = 1; $x < $y; $x++) 1479 { 1480 $next = array_shift($tempcategories); 1481 if( !(in_array($next, $categories)) ) $categories[] = $next; 1482 } 1483 } 1484 1485 1486 /** 1487 * Outputs a list of available renderers (not necessarily installed). 1488 */ 1489 function renderer_list() 1490 { 1491 global $renderers; 1492 1493 $admin_Plugins = & get_Cache('Plugins_admin'); // use Plugins_admin, because a plugin might be disabled 1494 $admin_Plugins->discover(); 1495 1496 $renderers = array('default'); 1497 $admin_Plugins->restart(); // make sure iterator is at start position 1498 while( $loop_RendererPlugin = & $admin_Plugins->get_next() ) 1499 { // Go through whole list of renders 1500 // echo ' ',$loop_RendererPlugin->code; 1501 if( empty($loop_RendererPlugin->code) ) 1502 { // No unique code! 1503 continue; 1504 } 1505 if( $loop_RendererPlugin->apply_rendering == 'stealth' 1506 || $loop_RendererPlugin->apply_rendering == 'never' ) 1507 { // This is not an option. 1508 continue; 1509 } 1510 elseif( $loop_RendererPlugin->code == 'b2WPAutP' ) 1511 { // special Auto-P plugin 1512 ?> 1513 <fieldset> 1514 <label for="textile" title="<?php echo format_to_output($loop_RendererPlugin->short_desc, 'formvalue'); ?>"><strong><?php echo format_to_output($loop_RendererPlugin->name) ?>:</strong></label> 1515 <div style="margin-left:2ex" /> 1516 <input type="radio" name="autop" value="1" class="checkbox" checked="checked" /> yes (always)<br> 1517 <input type="radio" name="autop" value="0" class="checkbox" /> no (never)<br> 1518 <input type="radio" name="autop" value="depends" class="checkbox" /> depends on CONVERT BREAKS 1519 <span class="notes"> ..that means it will apply if convert breaks results to true (set to either 1, textile_2 or __DEFAULT__ (and "Convert-breaks default" checked above)</span> 1520 1521 </div> 1522 </fieldset> 1523 <?php 1524 continue; 1525 } 1526 ?> 1527 <div> 1528 <input type="checkbox" class="checkbox" name="renderers[]" 1529 value="<?php echo $loop_RendererPlugin->code ?>" id="<?php echo $loop_RendererPlugin->code ?>" 1530 <?php 1531 switch( $loop_RendererPlugin->apply_rendering ) 1532 { 1533 case 'always': 1534 // echo 'FORCED'; 1535 echo ' checked="checked"'; 1536 echo ' disabled="disabled"'; 1537 break; 1538 1539 case 'opt-out': 1540 if( in_array( $loop_RendererPlugin->code, $renderers ) // Option is activated 1541 || in_array( 'default', $renderers ) ) // OR we're asking for default renderer set 1542 { 1543 // echo 'OPT'; 1544 echo ' checked="checked"'; 1545 } 1546 // else echo 'NO'; 1547 break; 1548 1549 case 'opt-in': 1550 if( in_array( $loop_RendererPlugin->code, $renderers ) ) // Option is activated 1551 { 1552 // echo 'OPT'; 1553 echo ' checked="checked"'; 1554 } 1555 // else echo 'NO'; 1556 break; 1557 1558 case 'lazy': 1559 // cannot select 1560 if( in_array( $loop_RendererPlugin->code, $renderers ) ) // Option is activated 1561 { 1562 // echo 'OPT'; 1563 echo ' checked="checked"'; 1564 } 1565 echo ' disabled="disabled"'; 1566 break; 1567 } 1568 ?> 1569 title="<?php echo format_to_output( $loop_RendererPlugin->short_desc, 'formvalue' ) ?>" /> 1570 <label for="<?php echo $loop_RendererPlugin->code ?>" title="<?php echo format_to_output($loop_RendererPlugin->short_desc, 'formvalue'); ?>"><strong><?php echo format_to_output($loop_RendererPlugin->name); ?></strong></label> 1571 </div> 1572 <?php 1573 } 1574 } 1575 1576 1577 /** 1578 * Die with a message. 1579 * 1580 * @param string the message (wrapped in div and p tag of class error) 1581 * @param string optional head 1582 */ 1583 function dieerror( $message, $before = '' ) 1584 { 1585 if( !empty($before) ) 1586 echo $before; 1587 1588 die( '<div class="error"><p class="error">'.$message.'</p></div> 1589 </div></body></html>' ); 1590 } 1591 1592 1593 function debug_dump( $var, $title = '' ) 1594 { 1595 global $output_debug_dump; 1596 1597 if( $output_debug_dump ) 1598 { 1599 pre_dump( $var, $title ); 1600 } 1601 } 1602 1603 1604 function chooseexportfile() 1605 { 1606 global $exportedfile, $import_mode; 1607 // Go through directory: 1608 $this_dir = dir( IMPORT_SRC_DIR ); 1609 $r = ''; 1610 while( $this_file = $this_dir->read() ) 1611 { 1612 if( preg_match( '/^.+\.txt$/i', $this_file ) ) 1613 { 1614 $r .= '<option value="'.format_to_output( $this_file, 'formvalue' ).'"'; 1615 if( $exportedfile == $this_file ) $r .= ' selected="selected"'; 1616 $r .= '>'.format_to_output( $this_file, 'entityencoded' ).'</option>'; 1617 } 1618 } 1619 1620 if( $r ) 1621 { 1622 ?> 1623 <form action="admin.php" class="center"> 1624 <p>First, choose a file to import (.TXT files from the b2evolution base directory):</p> 1625 <select name="exportedfile" onChange="submit()"> 1626 <?php echo $r ?> 1627 </select> 1628 <input type="hidden" name="import_mode" value="<?php echo $import_mode ?>" /> 1629 <input type="hidden" name="ctrl" value="mtimport" /> 1630 <input type="submit" value="Next step..." class="search" /> 1631 </form> 1632 <?php 1633 } 1634 else 1635 { // no file found 1636 ?> 1637 <div class="error"> 1638 <p class="center">No .TXT file found. Nothing to import...</p> 1639 <p class="center">Please copy your Movable Type .TXT export file into <?php echo rel_path_to_base(IMPORT_SRC_DIR); ?>.</p> 1640 </div> 1641 <?php 1642 } 1643 } 1644 1645 1646 function ripline( $prefix, &$haystack ) 1647 { 1648 if( preg_match( '|^'.$prefix.'(.*)|m', $haystack, $match ) ) 1649 { 1650 $haystack = preg_replace('|^'.$prefix.".*\n?|m", '', $haystack ); 1651 return trim( $match[1] ); 1652 } 1653 else return false; 1654 } 1655 1656 1657 function tidypostdata( $string ) 1658 { 1659 return str_replace( array('"', ''', '<', '>'), array('"', "'", '<', '>'), remove_magic_quotes( $string ) ); 1660 } 1661 1662 /* 1663 * $Log: mtimport.ctrl.php,v $ 1664 * Revision 1.3 2007/10/09 01:18:12 fplanque 1665 * Hari's WordPress importer 1666 * 1667 * Revision 1.2 2007/09/11 21:43:48 fplanque 1668 * fixed MT importer 1669 * 1670 * Revision 1.1 2007/06/25 11:01:40 fplanque 1671 * MODULES (refactored MVC) 1672 * 1673 * Revision 1.33 2007/05/14 02:43:04 fplanque 1674 * Started renaming tables. There probably won't be a better time than 2.0. 1675 * 1676 * Revision 1.32 2007/05/09 00:58:54 fplanque 1677 * massive cleanup of old functions 1678 * 1679 * Revision 1.31 2007/04/26 00:11:15 fplanque 1680 * (c) 2007 1681 * 1682 * Revision 1.30 2006/12/28 15:44:31 fplanque 1683 * login refactoring / simplified 1684 * 1685 * Revision 1.29 2006/12/17 23:42:38 fplanque 1686 * Removed special behavior of blog #1. Any blog can now aggregate any other combination of blogs. 1687 * Look into Advanced Settings for the aggregating blog. 1688 * There may be side effects and new bugs created by this. Please report them :] 1689 * 1690 * Revision 1.28 2006/12/03 18:22:58 blueyed 1691 * Nuked deprecated fileupload globals 1692 * 1693 * Revision 1.27 2006/12/01 20:04:31 blueyed 1694 * Renamed Plugins_admin::validate_list() to validate_renderer_list() 1695 * 1696 * Revision 1.26 2006/12/01 19:46:42 blueyed 1697 * Moved Plugins::validate_list() to Plugins_admin class; added stub in Plugins, because at least the starrating_plugin uses it 1698 * 1699 * Revision 1.25 2006/11/26 01:42:08 fplanque 1700 * doc 1701 */ 1702 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 23:58:50 2007 | par Balluche grâce à PHPXref 0.7 |
|