b2evolution PHP Cross Reference Blogging Systems

Source: /inc/tools/mtimport.ctrl.php - 1683 lines - 54541 bytes - Summary - Text - Print

Description: This file implements importing of Movable Type entries into b2evolution. {@internal TODO: - Wrap this by an abstract import class! - list of all posts, editable (overkill?) - assign comment_author_ID to comments if user exist?! }}

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

title

Description

title

Description

title

Description

title

title

Body