[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-forums/bbpress/bb-admin/includes/ -> class.bb-install.php (source)

   1  <?php
   2  /**
   3   * bbPress Installation class
   4   *
   5   * @since 0.9
   6   */
   7  class BB_Install
   8  {
   9      /**
  10       * The file where the class was instantiated
  11       *
  12       * @var string
  13       */
  14      var $caller;
  15  
  16      /**
  17       * Whether or not we need to load some of the includes normally loaded by bb-settings.php
  18       *
  19       * @var boolean
  20       */
  21      var $load_includes = false;
  22  
  23      /**
  24       * An array of available languages to use in the installer
  25       *
  26       * @var array
  27       */
  28      var $languages = array( 'en_US' => 'en_US' );
  29  
  30      /**
  31       * The currently selected language for the installer
  32       *
  33       * @var string
  34       */
  35      var $language = 'en_US';
  36  
  37      /**
  38       * The current step in the install process
  39       *
  40       * @var integer
  41       */
  42      var $step;
  43  
  44      /**
  45       * Info about config files and their locations
  46       *
  47       * @var array
  48       */
  49      var $configs = array(
  50          'writable' => false,
  51          'bb-config.php' => false,
  52          'config.php' => false
  53      );
  54  
  55      /**
  56       * An array of the current status of each step
  57       *
  58       * @var array
  59       */
  60      var $step_status = array(
  61          0 => 'incomplete',
  62          1 => 'incomplete',
  63          2 => 'incomplete',
  64          3 => 'incomplete',
  65          4 => 'incomplete'
  66      );
  67  
  68      /**
  69       * An array of most strings in use, including errors
  70       *
  71       * @var array
  72       */
  73      var $strings = array();
  74  
  75      /**
  76       * The data being manipulated as we go through the forms
  77       *
  78       * @var array
  79       */
  80      var $data = array();
  81  
  82      /**
  83       * A boolean that can get flagged to stop posting of a form getting processed
  84       *
  85       * @var boolean
  86       */
  87      var $stop_process = false;
  88  
  89      /**
  90       * Keeps track of where the tabindex is up to
  91       *
  92       * @var integer
  93       */
  94      var $tabindex = 0;
  95  
  96      /**
  97       * Constructor
  98       *
  99       * Loads everything we might need to do the business
 100       *
 101       * @param string $caller The full path of the file that instantiated the class
 102       * @return boolean Always returns true
 103       */
 104  	function __construct( $caller )
 105      {
 106          $this->caller = $caller;
 107  
 108          $this->set_initial_step();
 109          $this->define_paths();
 110  
 111          // We need to load these when bb-settings.php isn't loaded
 112          if ( $this->load_includes ) {
 113              require_once( BACKPRESS_PATH . 'functions.core.php' );
 114              require_once( BACKPRESS_PATH . 'functions.compat.php' );
 115              require_once( BACKPRESS_PATH . 'functions.formatting.php' );
 116              require_once( BACKPRESS_PATH . 'functions.plugin-api.php' );
 117              require_once( BACKPRESS_PATH . 'class.wp-error.php' );
 118              require_once( BB_PATH . BB_INC . 'functions.bb-core.php' );
 119              require_once( BB_PATH . BB_INC . 'functions.bb-meta.php' );
 120              require_once( BB_PATH . BB_INC . 'class.bp-options.php' );
 121              require_once( BACKPRESS_PATH . 'functions.bp-options.php' );
 122              require_once( BACKPRESS_PATH . 'functions.kses.php' );
 123              require_once( BB_PATH . BB_INC . 'functions.bb-l10n.php' );
 124              require_once( BB_PATH . BB_INC . 'functions.bb-template.php' );
 125          }
 126  
 127          $this->get_languages();
 128          $this->set_language();
 129  
 130          if ( $this->language ) {
 131              global $locale;
 132              global $l10n;
 133              $locale = $this->language;
 134              unset( $l10n['default'] );
 135  
 136              if ( !class_exists( 'MO' ) ) {
 137                  require_once( BACKPRESS_PATH . 'pomo/mo.php' );
 138              }
 139          }
 140  
 141          // Load the default text localization domain. Doing this twice doesn't hurt too much.
 142          bb_load_default_textdomain();
 143  
 144          // Pull in locale data after loading text domain.
 145          if ( $this->load_includes ) {
 146              require_once( BB_PATH . BB_INC . 'class.bb-locale.php' );
 147          }
 148          global $bb_locale;
 149          $bb_locale = new BB_Locale();
 150  
 151          $this->prepare_strings();
 152          $this->check_prerequisites();
 153          $this->check_configs();
 154  
 155          if ( $this->step > -1 ) {
 156              $this->set_step();
 157              $this->prepare_data();
 158              $this->process_form();
 159          }
 160  
 161          return true;
 162      }
 163  
 164  	function BB_Install( $caller ) {
 165          $this->__construct( $caller );
 166      }
 167  
 168      /**
 169       * Set initial step
 170       *
 171       * Sets the step from the post data and keeps it within range
 172       *
 173       * @return integer The calculated step
 174       */
 175  	function set_initial_step()
 176      {
 177          // Set the step based on the $_POST value or 0
 178          $this->step = $_POST['step'] ? (integer) $_POST['step'] : 0;
 179  
 180          // Make sure the requested step is from 0-4
 181          if ( 0 > $this->step || 4 < $this->step ) {
 182              $this->step = 0;
 183          }
 184          return $this->step;
 185      }
 186  
 187      /**
 188       * Prepare text strings
 189       *
 190       * Sets up many of the strings to be used by the class that may
 191       * be later subject to change due to processing of the forms
 192       */
 193  	function prepare_strings()
 194      {
 195          $this->strings = array(
 196              -1 => array(
 197                  'title'       => __( 'bbPress &rsaquo; Error' ),
 198                  'h1'          => __( 'Oh dear!' ),
 199                  'messages'    => array()
 200              ),
 201              0 => array(
 202                  'title'       => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Welcome' ) ),
 203                  'h2'          => __( 'Welcome to the bbPress installer' ),
 204                  'status'      => '',
 205                  'messages'    => array(),
 206                  'intro'       => array(
 207                      __( 'We\'re now going to go through a few steps to get you up and running.' ),
 208                      __( 'Ready? Then let\'s get started!' )
 209                  )
 210              ),
 211              1 => array(
 212                  'title'       => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 1' ) ),
 213                  'h2'          => sprintf( __( '%1$s - %2$s' ), __( 'Step 1' ), __( 'Database configuration' ) ),
 214                  'status'      => '',
 215                  'intro'       => array(
 216                      __( 'In this step you need to enter your database connection details. The installer will attempt to create a file called <code>bb-config.php</code> in the root directory of your bbPress installation.' ),
 217                      __( 'If you\'re not sure what to put here, contact your web hosting provider.' )
 218                  ),
 219                  'messages'    => array()
 220              ),
 221              2 => array(
 222                  'title'       => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 2' ) ),
 223                  'h2'          => sprintf( __( '%1$s - %2$s' ), __( 'Step 2' ), __( 'WordPress integration (optional)' ) ),
 224                  'status'      => __( '&laquo; skipped' ),
 225                  'intro'       => array(
 226                      __( 'bbPress can integrate login and user data seamlessly with WordPress. You can safely skip this step if you do not wish to integrate with an existing WordPress install.' )
 227                  ),
 228                  'messages'    => array(),
 229                  'form_errors' => array()
 230              ),
 231              3 => array(
 232                  'title'       => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 3' ) ),
 233                  'h2'          => sprintf( __( '%1$s - %2$s' ), __( 'Step 3' ), __( 'Site settings' ) ),
 234                  'status'      => '',
 235                  'intro'       => array(
 236                      __( 'Finalize your installation by adding a name, your first user and your first forum.' )
 237                  ),
 238                  'messages'    => array(),
 239                  'form_errors' => array(),
 240                  'scripts'     => array()
 241              ),
 242              4 => array(
 243                  'title'       => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Finished' ) ),
 244                  'h2'          => __( 'Installation complete!' ),
 245                  'messages'    => array()
 246              )
 247          );
 248      }
 249  
 250      /**
 251       * Check installation pre-requisites
 252       *
 253       * Checks for appropriate PHP extensions.
 254       *
 255       * @return boolean False if any pre-requisites are not met, otherwise true
 256       */
 257  	function check_prerequisites()
 258      {
 259          // BPDB wants the MySQL extension - this is also checked when BPDB is initialised so may be a bit redundant here
 260          if ( !extension_loaded( 'mysql' ) ) {
 261              $this->strings[-1]['messages']['error'][] = __( 'Your PHP installation appears to be missing the MySQL extension which is required for bbPress' );
 262              $this->step = -1;
 263          }
 264  
 265          if ( defined( 'BB_IS_WP_LOADED' ) && BB_IS_WP_LOADED ) {
 266              $this->strings[-1]['messages']['error'][] = __( 'Please complete your installation before attempting to include WordPress within bbPress' );
 267              $this->step = -1;
 268          }
 269  
 270          if ( $this->step === -1 ) {
 271              return false;
 272          }
 273  
 274          return true;
 275      }
 276  
 277      /**
 278       * Define path constants
 279       *
 280       * Sets some bbPress constants if they are not otherwise available based
 281       * on the classes initiating file path.
 282       *
 283       * @return boolean False if no path was supplied, otherwise always true
 284       */
 285  	function define_paths()
 286      {
 287          if ( !$this->caller ) {
 288              return false;
 289          }
 290  
 291          if ( !defined( 'BACKPRESS_PATH' ) ) {
 292              // Define BACKPRESS_PATH
 293              // Tell us to load includes because bb-settings.php was not loaded
 294              // bb-settings.php is generally not loaded on steps -1, 0 and 1 but
 295              // there are exceptions, so this is safer than just reading the step
 296              $this->load_includes = true;
 297              define( 'BACKPRESS_PATH', BB_PATH . BB_INC . 'backpress/' );
 298          }
 299  
 300          // Define the language file directory
 301          if ( !defined( 'BB_LANG_DIR' ) ) {
 302              define( 'BB_LANG_DIR', BB_PATH . 'my-languages/' );
 303          }
 304  
 305          return true;
 306      }
 307  
 308      /**
 309       * Gets an array of available languages form the language directory
 310       *
 311       * @return array
 312       */
 313  	function get_languages()
 314      {
 315          foreach ( bb_glob( BB_LANG_DIR . '*.mo' ) as $language ) {
 316              if ( substr( $language, 0, 18 ) === 'continents-cities-' ) {
 317                  continue;
 318              }
 319              $language = str_replace( '.mo', '', basename( $language ) );
 320              $this->languages[$language] = $language;
 321          }
 322          
 323          return $this->languages;
 324      }
 325  
 326      /**
 327       * Returns a language selector for switching installation languages
 328       *
 329       * @return string|false Either the html for the selector or false if there are no languages
 330       */
 331  	function get_language_selector()
 332      {
 333          // Don't provide a selection if there is only english
 334          if ( 2 > count( $this->languages ) ) {
 335              return false;
 336          }
 337  
 338          $r = '<script type="text/javascript" charset="utf-8">' . "\n";
 339          $r .= "\t" . 'function changeLanguage(selectObj) {' . "\n";
 340          $r .= "\t\t" . 'var selectedLanguage = selectObj.options[selectObj.selectedIndex].value;' . "\n";
 341          $r .= "\t\t" . 'location.href = "install.php?language=" + selectedLanguage;' . "\n";
 342          $r .= "\t" . '}' . "\n";
 343          $r .= '</script>' . "\n";
 344          //$r .= '<form id="lang" action="install.php">' . "\n";
 345          $r .= "\t" . '<fieldset>' . "\n";
 346          $r .= "\t\t" . '<label class="has-note has-label for-select">' . "\n";
 347          $r .= "\t\t\t" . '<span>' . __( 'Installation language' ) . '</span>' . "\n";
 348          $this->tabindex++;
 349          $r .= "\t\t\t" . '<select class="has-note" onchange="changeLanguage(this);" name="language" tabindex="' . $this->tabindex . '">' . "\n";
 350          foreach ( $this->languages as $language ) {
 351              $selected = '';
 352              if ( $language == $this->language ) {
 353                  $selected = ' selected="selected"';
 354              }
 355              $r .= "\t\t\t\t" . '<option value="' . $language . '"' . $selected . '>' . $language . '</option>' . "\n";
 356          }
 357          $r .= "\t\t\t" . '</select>' . "\n";
 358          $r .= "\t\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-language\');">?</a>' . "\n";
 359          $r .= "\t\t\t" . '<p id="note-language" class="note" style="display:none">' . __( 'Sets the language to be used during the installation process only.' ) . '</p>' . "\n";
 360          $r .= "\t\t\t" . '<div class="clear"></div>' . "\n";
 361          $r .= "\t\t" . '</label>' . "\n";
 362          $r .= "\t" . '</fieldset>' . "\n";
 363          //$r .= '</form>' . "\n";
 364  
 365          echo $r;
 366      }
 367  
 368      /**
 369       * Sets the current installation language
 370       *
 371       * @return string The currently set language
 372       */
 373  	function set_language()
 374      {
 375          if ( isset( $_COOKIE['bb_install_language'] ) && 1 < count( $this->languages ) ) {
 376              if ( in_array( $_COOKIE['bb_install_language'], $this->languages ) ) {
 377                  $this->language = $_COOKIE['bb_install_language'];
 378              }
 379          }
 380  
 381          $language_requested = false;
 382          if ( isset( $_POST['language'] ) && $_POST['language'] ) {
 383              $language_requested = (string) $_POST['language'];
 384          } elseif ( isset( $_GET['language'] ) && $_GET['language'] ) {
 385              $language_requested = (string) $_GET['language'];
 386          }
 387  
 388          if ( $language_requested && 1 < count( $this->languages ) ) {
 389              if ( in_array( $language_requested, $this->languages ) ) {
 390                  $this->language = $language_requested;
 391                  setcookie( 'bb_install_language', $this->language );
 392              }
 393          }
 394  
 395          if ( !$this->language || 'en_US' === $this->language ) {
 396              $this->language = 'en_US';
 397              setcookie( 'bb_install_language', ' ', time() - 31536000 );
 398          }
 399  
 400          return $this->language;
 401      }
 402  
 403      /**
 404       * Tests whether database tables exist
 405       *
 406       * Checks for the existence of the forum table in the database that is
 407       * currently configured.
 408       *
 409       * @return boolean False if the table isn't found, otherwise true
 410       */
 411  	function database_tables_are_installed()
 412      {
 413          global $bbdb;
 414          $bbdb->suppress_errors();
 415          $installed = (boolean) $bbdb->get_results( 'DESCRIBE `' . $bbdb->forums . '`;', ARRAY_A );
 416          $bbdb->suppress_errors( false );
 417          return $installed;
 418      }
 419  
 420      /**
 421       * Tests whether an option is set in the database
 422       *
 423       * @return boolean False if the option isn't set, otherwise true
 424       */
 425  	function bb_options_are_set()
 426      {
 427          if ( $this->load_includes ) {
 428              return false;
 429          }
 430          if ( !bb_get_option( 'uri' ) ) {
 431              return false;
 432          }
 433          return true;
 434      }
 435  
 436      /**
 437       * Tests whether bbPress is installed
 438       *
 439       * @return boolean False if bbPress isn't installed, otherwise true
 440       */
 441  	function is_installed()
 442      {
 443          if ( !$this->database_tables_are_installed() ) {
 444              return false;
 445          }
 446          if ( !$this->bb_options_are_set() ) {
 447              return false;
 448          }
 449          return true;
 450      }
 451  
 452      /**
 453       * Checks for configs and sets variables describing current install state
 454       *
 455       * @return integer The current step we should be on based on the existence of the config file
 456       */
 457  	function check_configs()
 458      {
 459          // Check for a config file
 460          if ( file_exists( BB_PATH . 'bb-config.php' ) ) {
 461              $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
 462          } elseif ( file_exists( dirname( BB_PATH ) . '/bb-config.php' ) ) {
 463              $this->configs['bb-config.php'] = dirname( BB_PATH ) . '/bb-config.php';
 464          }
 465  
 466          // Check for an old config file
 467          if ( file_exists( BB_PATH . 'config.php' ) ) {
 468              $this->configs['config.php'] = BB_PATH . 'config.php';
 469          } elseif ( file_exists( dirname( BB_PATH ) . '/config.php' ) ) {
 470              $this->configs['config.php'] = dirname( BB_PATH ) . '/config.php';
 471          }
 472  
 473          if ( $this->configs['config.php'] && !$this->configs['bb-config.php'] ) {
 474              // There is an old school config file
 475              // Step -1 is where we send fatal errors from any screen
 476              $this->strings[-1]['messages']['error'][] = __( 'An old <code>config.php</code> file has been detected in your installation. You should remove it and run the <a href="install.php">installer</a> again. You can use the same database connection details if you do.' );
 477              $this->step = -1;
 478              return $this->step;
 479          }
 480  
 481          // Check if bbPress is already installed
 482          // Is there a current config file
 483          if ( $this->configs['bb-config.php'] ) {
 484  
 485              // Is it valid
 486              if ( $this->validate_current_config() ) {
 487                  // Step 1 is complete
 488                  $this->step_status[1] = 'complete';
 489                  $this->strings[1]['status'] = __( '&laquo; completed' );
 490  
 491                  // On step 1 we want to report that the file is good and allow the user to continue
 492                  if ( $this->step === 1 ) {
 493                      // Stop form processing if it is posted
 494                      $this->stop_process = true;
 495  
 496                      // Display a nice message saying the config file exists
 497                      $this->strings[1]['messages']['message'][] = __( 'A valid configuration file was found at <code>bb-config.php</code><br />You may continue to the next step.' );
 498                      return $this->step;
 499                  }
 500              } else {
 501                  // Invalid config files on any step cause us to exit to step 0
 502                  $this->strings[-1]['messages']['error'][] = __( 'An invalid configuration file was found at <code>bb-config.php</code><br />The installation cannot continue.' );
 503                  $this->strings[-1]['messages'][0][] = __( 'Usually this is caused by one of the database connection settings being incorrect. Make sure that the specified user has appropriate permission to access the database.' );
 504                  $this->step = -1;
 505              }
 506  
 507              // If we have made it this far, then we can check if the database tables exist and have content
 508              if ( $this->is_installed() ) {
 509                  // The database is installed
 510                  // The following standard functions should be available
 511                  if ( bb_get_option( 'bb_db_version' ) > bb_get_option_from_db( 'bb_db_version' ) ) {
 512                      // The database needs upgrading
 513                      $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed, but appears to require an upgrade.' );
 514                  } else {
 515                      $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed.' );
 516                  }
 517                  $this->strings[-1]['messages'][0][] = sprintf(
 518                      __( 'Perhaps you meant to run the <a href="%s">upgrade script</a> instead?' ),
 519                      bb_get_uri( 'bb-admin/upgrade.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN )
 520                  );
 521                  $this->step = -1;
 522              }
 523  
 524          } else {
 525  
 526              if ( 2 > $this->step && !file_exists( BB_PATH . 'bb-config-sample.php' ) ) {
 527                  // There is no sample config file
 528                  $this->strings[0]['messages']['error'][] = __( 'I could not find the file <code>bb-config-sample.php</code><br />Please upload it to the root directory of your bbPress installation.' );
 529                  $this->step = 0;
 530              }
 531  
 532              if ( 1 !== $this->step ) {
 533                  // There is no config file, go back to the beginning
 534                  $this->strings[0]['messages']['message'][] = __( 'There doesn\'t seem to be a <code>bb-config.php</code> file. This usually means that you want to install bbPress.' );
 535                  $this->step = 0;
 536              }
 537  
 538          }
 539  
 540          // Check if the config file path is writable
 541          if ( file_exists( $this->configs['bb-config.php'] ) ) {
 542              if ( is_writable( $this->configs['bb-config.php'] ) ) {
 543                  $this->configs['writable'] = true;
 544              }
 545          } elseif ( is_writable( BB_PATH ) ) {
 546              $this->configs['writable'] = true;
 547          }
 548  
 549          return $this->step;
 550      }
 551  
 552      /**
 553       * Determines if the current config is valid
 554       *
 555       * @return boolean False if the config is bad, otherwise true
 556       */
 557  	function validate_current_config()
 558      {
 559          // If we are validating then the config file has already been included
 560          // So we can just check for valid constants
 561  
 562          // The required constants for a valid config file
 563          $required_constants = array(
 564              'BBDB_NAME',
 565              'BBDB_USER',
 566              'BBDB_PASSWORD',
 567              'BBDB_HOST'
 568          );
 569  
 570          // Check the required constants are defined
 571          foreach ( $required_constants as $required_constant ) {
 572              if ( !defined( $required_constant ) ) {
 573                  return false;
 574              }
 575          }
 576  
 577          global $bb_table_prefix;
 578  
 579          if ( !isset( $bb_table_prefix ) ) {
 580              return false;
 581          }
 582  
 583          // Everthing is OK so far, validate the connection as well
 584          return $this->validate_current_database();
 585      }
 586  
 587      /**
 588       * Validates the current database settings
 589       *
 590       * @return boolean False if the current database isn't valid, otherwise true
 591       */
 592  	function validate_current_database()
 593      {
 594          global $bbdb;
 595          $db = $bbdb->db_connect( "SELECT * FROM $bbdb->forums LIMIT 1" );
 596  
 597          if ( !is_resource( $db ) ) {
 598              return false;
 599          }
 600  
 601          return true;
 602      }
 603  
 604      /**
 605       * Sets up default values for input data as well as labels and notes
 606       *
 607       * @return void
 608       */
 609  	function prepare_data()
 610      {
 611          /**
 612           * Should be exactly the same as the default value of the KEYS in bb-config-sample.php
 613           * @since 1.0
 614           */
 615          $_bb_default_secret_key = 'put your unique phrase here';
 616  
 617          $this->data = array(
 618              0 => array(
 619                  'form' => array(
 620                      'forward_0_0' => array(
 621                          'value' => __( 'Go to step 1' )
 622                      )
 623                  )
 624              ),
 625              1 => array(
 626                  'form' => array(
 627                      'bbdb_name' => array(
 628                          'value' => '',
 629                          'label' => __( 'Database name' ),
 630                          'note'  => __( 'The name of the database in which you want to run bbPress.' )
 631                      ),
 632                      'bbdb_user' => array(
 633                          'value' => '',
 634                          'label' => __( 'Database user' ),
 635                          'note'  => __( 'The database user that has access to that database.' ),
 636                          'autocomplete' => 'off'
 637                      ),
 638                      'bbdb_password' => array(
 639                          'type'  => 'password',
 640                          'value' => '',
 641                          'label' => __( 'Database password' ),
 642                          'note'  => __( 'That database user\'s password.' ),
 643                          'autocomplete' => 'off'
 644                      ),
 645                      'bb_lang' => array(
 646                          'value' => '',
 647                          'label' => __( 'Language' ),
 648                          'note' => sprintf( __( 'The language which bbPress will be presented in once installed. Your current installer language choice (%s) will be the same for the rest of the install process.' ), $this->language )
 649                      ),
 650                      'toggle_1' => array(
 651                          'value'   => 0,
 652                          'label'   => __( 'Show advanced settings' ),
 653                          'note'    => __( 'These settings usually do not have to be changed.' ),
 654                          'checked' => '',
 655                          'display' => 'none'
 656                      ),
 657                      'bbdb_host'        => array(
 658                          'value'        => 'localhost',
 659                          'label'        => __( 'Database host' ),
 660                          'note'         => __( 'The domain name or IP address of the server where the database is located. If the database is on the same server as the web site, then this probably should remain <strong>localhost</strong>.' ),
 661                          'prerequisite' => 'toggle_1'
 662                      ),
 663                      'bbdb_charset' => array(
 664                          'value'        => 'utf8',
 665                          'label'        => __( 'Database character set' ),
 666                          'note'         => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
 667                          'prerequisite' => 'toggle_1'
 668                      ),
 669                      'bbdb_collate' => array(
 670                          'value'        => '',
 671                          'label'        => __( 'Database character collation' ),
 672                          'note'         => __( 'The character collation value set when the database was created.' ),
 673                          'prerequisite' => 'toggle_1'
 674                      ),
 675                      /*
 676                      'bb_auth_key' => array(
 677                          'value'        => $_bb_default_secret_key,
 678                          'label'        => __( 'bbPress "auth" cookie key' ),
 679                          'note'         => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "auth" cookie unique and harder for an attacker to decipher.' ),
 680                          'prerequisite' => 'toggle_1'
 681                      ),
 682                      'bb_secure_auth_key' => array(
 683                          'value'        => $_bb_default_secret_key,
 684                          'label'        => __( 'bbPress "secure auth" cookie key' ),
 685                          'note'         => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "secure auth" cookie unique and harder for an attacker to decipher.' ),
 686                          'prerequisite' => 'toggle_1'
 687                      ),
 688                      'bb_logged_in_key' => array(
 689                          'value'        => $_bb_default_secret_key,
 690                          'label'        => __( 'bbPress "logged in" cookie key' ),
 691                          'note'         => __( 'This should be a unique and secret phrase, it will be used to make your bbPress "logged in" cookie unique and harder for an attacker to decipher.' ),
 692                          'prerequisite' => 'toggle_1'
 693                      ),
 694                      'bb_nonce_key' => array(
 695                          'value'        => $_bb_default_secret_key,
 696                          'label'        => __( 'bbPress "nonce" key' ),
 697                          'note'         => __( 'This should be a unique and secret phrase, it will be used to make form submission harder for an attacker to spoof.' ),
 698                          'prerequisite' => 'toggle_1'
 699                      ),
 700                      */
 701                      'bb_table_prefix' => array(
 702                          'value'        => 'bb_',
 703                          'label'        => __( 'Table name prefix' ),
 704                          'note'         => __( 'If you are running multiple bbPress sites in a single database, you will probably want to change this.' ),
 705                          'prerequisite' => 'toggle_1'
 706                      ),
 707                      'config' => array(
 708                          'value' => '',
 709                          'label' => __( 'Contents for <code>bb-config.php</code>' ),
 710                          'note'  => __( 'Once you have created the configuration file, you can check for it below.' )
 711                      ),
 712                      'forward_1_0' => array(
 713                          'value' => __( 'Save database configuration file' )
 714                      ),
 715                      'back_1_1' => array(
 716                          'value' => __( '&laquo; Go back' )
 717                      ),
 718                      'forward_1_1' => array(
 719                          'value' => __( 'Check for configuration file' )
 720                      ),
 721                      'forward_1_2' => array(
 722                          'value' => __( 'Go to step 2' )
 723                      )
 724                  )
 725              ),
 726  
 727              2 => array(
 728                  'form' => array(
 729                      'toggle_2_0' => array(
 730                          'value'        => 0,
 731                          'label'        => __( 'Add integration settings' ),
 732                          'note'         => __( 'If you want to integrate bbPress with an existing WordPress site.' ),
 733                          'checked'      => '',
 734                          'display'      => 'none',
 735                          'toggle_value' => array(
 736                              'target'    => 'forward_2_0',
 737                              'off_value' => __( 'Skip WordPress integration' ),
 738                              'on_value'  => __( 'Save WordPress integration settings' )
 739                          )
 740                      ),
 741                      'toggle_2_1' => array(
 742                          'value'   => 0,
 743                          'label'   => __( 'Add cookie integration settings' ),
 744                          'note'    => __( 'If you want to allow shared logins with an existing WordPress site.' ),
 745                          'checked' => '',
 746                          'display' => 'none',
 747                          'prerequisite' => 'toggle_2_0'
 748                      ),
 749                      'wp_siteurl' => array(
 750                          'value' => '',
 751                          'label' => __( 'WordPress address (URL)' ),
 752                          'note'  => __( 'This value should exactly match the <strong>WordPress address (URL)</strong> setting in your WordPress general settings.' ),
 753                          'prerequisite' => 'toggle_2_1'
 754                      ),
 755                      'wp_home' => array(
 756                          'value' => '',
 757                          'label' => __( 'Blog address (URL)' ),
 758                          'note'  => __( 'This value should exactly match the <strong>Blog address (URL)</strong> setting in your WordPress general settings.' ),
 759                          'prerequisite' => 'toggle_2_1'
 760                      ),
 761                      'wp_auth_key' => array(
 762                          'value' => '',
 763                          'label' => __( 'WordPress "auth" cookie key' ),
 764                          'note'  => __( 'This value must match the value of the constant named "AUTH_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "auth" cookie key set in the first step.' ),
 765                          'prerequisite' => 'toggle_2_1',
 766                          'autocomplete' => 'off'
 767                      ),
 768                      'wp_auth_salt' => array(
 769                          'value' => '',
 770                          'label' => __( 'WordPress "auth" cookie salt' ),
 771                          'note'  => __( 'This must match the value of the WordPress setting named "auth_salt" in your WordPress site. Look for the option labeled "auth_salt" in <a href="#" id="getAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings.' ),
 772                          'prerequisite' => 'toggle_2_1',
 773                          'autocomplete' => 'off'
 774                      ),
 775                      'wp_secure_auth_key' => array(
 776                          'value' => '',
 777                          'label' => __( 'WordPress "secure auth" cookie key' ),
 778                          'note'  => __( 'This value must match the value of the constant named "SECURE_AUTH_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "secure auth" cookie key set in the first step.' ),
 779                          'prerequisite' => 'toggle_2_1',
 780                          'autocomplete' => 'off'
 781                      ),
 782                      'wp_secure_auth_salt' => array(
 783                          'value' => '',
 784                          'label' => __( 'WordPress "secure auth" cookie salt' ),
 785                          'note'  => __( 'This must match the value of the WordPress setting named "secure_auth_salt" in your WordPress site. Look for the option labeled "secure_auth_salt" in <a href="#" id="getSecureAuthSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings. Sometimes this value is not set in WordPress, in that case you can leave this setting blank as well.' ),
 786                          'prerequisite' => 'toggle_2_1',
 787                          'autocomplete' => 'off'
 788                      ),
 789                      'wp_logged_in_key' => array(
 790                          'value' => '',
 791                          'label' => __( 'WordPress "logged in" cookie key' ),
 792                          'note'  => __( 'This value must match the value of the constant named "LOGGED_IN_KEY" in your WordPress <code>wp-config.php</code> file. This will replace the bbPress "logged in" cookie key set in the first step.' ),
 793                          'prerequisite' => 'toggle_2_1',
 794                          'autocomplete' => 'off'
 795                      ),
 796                      'wp_logged_in_salt' => array(
 797                          'value' => '',
 798                          'label' => __( 'WordPress "logged in" cookie salt' ),
 799                          'note'  => __( 'This must match the value of the WordPress setting named "logged_in_salt" in your WordPress site. Look for the option labeled "logged_in_salt" in <a href="#" id="getLoggedInSaltOption" onclick="window.open(this.href); return false;">this WordPress admin page</a>. If you leave this blank the installer will try to fetch the value based on your WordPress database integration settings.' ),
 800                          'prerequisite' => 'toggle_2_1',
 801                          'autocomplete' => 'off'
 802                      ),
 803                      'toggle_2_2' => array(
 804                          'value'   => 0,
 805                          'label'   => __( 'Add user database integration settings' ),
 806                          'note'    => __( 'If you want to share user data with an existing WordPress site.' ),
 807                          'checked' => '',
 808                          'display' => 'none',
 809                          'prerequisite' => 'toggle_2_0'
 810                      ),
 811                      'wp_table_prefix' => array(
 812                          'value' => 'wp_',
 813                          'default_value' => '', // Used when setting is ignored
 814                          'label' => __( 'User database table prefix' ),
 815                          'note'  => __( 'If your bbPress and WordPress sites share the same database, then this is the same value as <code>$table_prefix</code> in your WordPress <code>wp-config.php</code> file. It is usually <strong>wp_</strong>.' ),
 816                          'prerequisite' => 'toggle_2_2'
 817                      ),
 818                      'wordpress_mu_primary_blog_id' => array(
 819                          'value' => '',
 820                          'default_value' => '',
 821                          'label' => __( 'WordPress MU primary blog ID' ),
 822                          'note'  => __( 'If you are integrating with a WordPress MU site you need to specify the primary blog ID for that site. It is usually <strong>1</strong>. You should probably leave this blank if you are integrating with a standard WordPress site' ),
 823                          'prerequisite' => 'toggle_2_2'
 824                      ),
 825                      'toggle_2_3' => array(
 826                          'value'   => 0,
 827                          'label'   => __( 'Show advanced database settings' ),
 828                          'note'    => __( 'If your bbPress and WordPress site do not share the same database, then you will need to add advanced settings.' ),
 829                          'checked' => '',
 830                          'display' => 'none',
 831                          'prerequisite' => 'toggle_2_2'
 832                      ),
 833                      'user_bbdb_name' => array(
 834                          'value' => '',
 835                          'label' => __( 'User database name' ),
 836                          'note'  => __( 'The name of the database in which your user tables reside.' ),
 837                          'prerequisite' => 'toggle_2_3'
 838                      ),
 839                      'user_bbdb_user' => array(
 840                          'value' => '',
 841                          'label' => __( 'User database user' ),
 842                          'note'  => __( 'The database user that has access to that database.' ),
 843                          'prerequisite' => 'toggle_2_3',
 844                          'autocomplete' => 'off'
 845                      ),
 846                      'user_bbdb_password' => array(
 847                          'type'  => 'password',
 848                          'value' => '',
 849                          'label' => __( 'User database password' ),
 850                          'note'  => __( 'That database user\'s password.' ),
 851                          'prerequisite' => 'toggle_2_3',
 852                          'autocomplete' => 'off'
 853                      ),
 854                      'user_bbdb_host' => array(
 855                          'value' => '',
 856                          'label' => __( 'User database host' ),
 857                          'note'  => __( 'The domain name or IP address of the server where the database is located. If the database is on the same server as the web site, then this probably should be <strong>localhost</strong>.' ),
 858                          'prerequisite' => 'toggle_2_3'
 859                      ),
 860                      'user_bbdb_charset' => array(
 861                          'value' => '',
 862                          'label' => __( 'User database character set' ),
 863                          'note'  => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
 864                          'prerequisite' => 'toggle_2_3'
 865                      ),
 866                      'user_bbdb_collate' => array(
 867                          'value' => '',
 868                          'label' => __( 'User database character collation' ),
 869                          'note'  => __( 'The character collation value set when the user database was created.' ),
 870                          'prerequisite' => 'toggle_2_3'
 871                      ),
 872                      'custom_user_table' => array(
 873                          'value' => '',
 874                          'label' => __( 'User database "user" table' ),
 875                          'note'  => __( 'The complete table name, including any prefix.' ),
 876                          'prerequisite' => 'toggle_2_3'
 877                      ),
 878                      'custom_user_meta_table' => array(
 879                          'value' => '',
 880                          'label' => __( 'User database "user meta" table' ),
 881                          'note'  => __( 'The complete table name, including any prefix.' ),
 882                          'prerequisite' => 'toggle_2_3'
 883                      ),
 884                      'forward_2_0' => array(
 885                          'value' => __( 'Skip WordPress integration' )
 886                      ),
 887                      'back_2_1' => array(
 888                          'value' => __( '&laquo; Go back' )
 889                      ),
 890                      'forward_2_1' => array(
 891                          'value' => __( 'Go to step 3' )
 892                      )
 893                  )
 894              ),
 895  
 896              3 => array(
 897                  'form' => array(
 898                      'name' => array(
 899                          'value' => '',
 900                          'label' => __( 'Site name' ),
 901                          'note'  => __( 'This is what you are going to call your bbPress site.' )
 902                      ),
 903                      'uri' => array(
 904                          'value' => $this->guess_uri(),
 905                          'label' => __( 'Site address (URL)' ),
 906                          'note'  => __( 'We have attempted to guess this; it\'s usually correct, but change it here if you wish.' )
 907                      ),
 908                      'keymaster_user_login' => array(
 909                          'value'     => '',
 910                          'maxlength' => 60,
 911                          'label'     => __( '"Key Master" Username' ),
 912                          'note'      => __( 'This is the user login for the initial bbPress administrator (known as a "Key Master").' ),
 913                          'autocomplete' => 'off'
 914                      ),
 915                      'keymaster_user_email' => array(
 916                          'value'     => '',
 917                          'maxlength' => 100,
 918                          'label'     => __( '"Key Master" Email address' ),
 919                          'note'      => __( 'The login details will be emailed to this address.' ),
 920                          'autocomplete' => 'off'
 921                      ),
 922                      'keymaster_user_type' => array(
 923                          'value' => 'new'
 924                      ),
 925                      'forum_name' => array(
 926                          'value'     => '',
 927                          'maxlength' => 150,
 928                          'label'     => __( 'First forum name' ),
 929                          'note'      => __( 'This can be changed after installation, so don\'t worry about it too much.' )
 930                      ),
 931                      'forward_3_0' => array(
 932                          'value' => __( 'Save site settings' )
 933                      ),
 934                      'back_3_1' => array(
 935                          'value' => __( '&laquo; Go back' )
 936                      ),
 937                      'forward_3_1' => array(
 938                          'value' => __( 'Complete the installation' )
 939                      )
 940                  )
 941              ),
 942  
 943              4 => array(
 944                  'form' => array(
 945                      'toggle_4' => array(
 946                          'value' => 0,
 947                          'label' => __( 'Show installation messages' )
 948                      ),
 949                      'error_log' => array(
 950                          'value' => '',
 951                          'label' => __( 'Installation errors' )
 952                      ),
 953                      'installation_log' => array(
 954                          'value' => '',
 955                          'label' => __( 'Installation log' )
 956                      )
 957                  )
 958              )
 959          );
 960      }
 961  
 962      /**
 963       * Guesses the final installed URI based on the location of the install script
 964       *
 965       * @return string The guessed URI
 966       */
 967  	function guess_uri()
 968      {
 969          global $bb;
 970  
 971          if ( $bb->uri ) {
 972              $uri = $bb->uri;
 973          } else {
 974              $schema = 'http://';
 975              if ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' ) {
 976                  $schema = 'https://';
 977              }
 978              $uri = preg_replace( '|/bb-admin/.*|i', '/', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
 979          }
 980  
 981          return rtrim( $uri, " \t\n\r\0\x0B/" ) . '/';
 982      }
 983  
 984      /**
 985       * Writes the given alterations to file
 986       *
 987       * @param $file_source string The full path to the file to be read from
 988       * @param $file_target string The full path to the file to be written to
 989       * @param $alterations array An array of arrays containing alterations to be made
 990       * @return void
 991       */
 992  	function write_lines_to_file( $file_source, $file_target, $alterations )
 993      {
 994          if ( !$file_source || !file_exists( $file_source ) || !is_file( $file_source ) ) {
 995              return -1;
 996          }
 997  
 998          if ( !$file_target ) {
 999              $file_target = $file_source;
1000          }
1001  
1002          if ( !$alterations || !is_array( $alterations ) ) {
1003              return -2;
1004          }
1005  
1006          /*
1007          Alterations array takes the form
1008          array(
1009              '1st 20 chars of line' => array( 'Search string', 'Replacement string' ),
1010              '1st 20 chars of line' => array( 'Search string', 'Replacement string' )
1011          );
1012          */
1013  
1014          // Get the existing lines in the file
1015          $lines = file( $file_source );
1016  
1017          // Initialise an array to store the modified lines
1018          $modified_lines = array();
1019  
1020          // Loop through the lines and modify them
1021          foreach ( $lines as $line ) {
1022              if ( isset( $alterations[substr( $line, 0, 20 )] ) ) {
1023                  $alteration = $alterations[substr( $line, 0, 20 )];
1024                  $modified_lines[] = str_replace( $alteration[0], $alteration[1], $line );
1025              } else {
1026                  $modified_lines[] = $line;
1027              }
1028          }
1029  
1030          $writable = true;
1031          if ( file_exists( $file_target ) ) {
1032              if ( !is_writable( $file_target ) ) {
1033                  $writable = false;
1034              }
1035          } else {
1036              $dir_target = dirname( $file_target );
1037              if ( file_exists( $dir_target ) ) {
1038                  if ( !is_writable( $dir_target ) || !is_dir( $dir_target ) ) {
1039                      $writable = false;
1040                  }
1041              } else {
1042                  $writable = false;
1043              }
1044          }
1045  
1046          if ( !$writable ) {
1047              return trim( join( null, $modified_lines ) );
1048          }
1049  
1050          // Open the file for writing - rewrites the whole file
1051          $file_handle = fopen( $file_target, 'w' );
1052  
1053          // Write lines one by one to avoid OS specific newline hassles
1054          foreach ( $modified_lines as $modified_line ) {
1055              if ( false !== strpos( $modified_line, '?>' ) ) {
1056                  $modified_line = '?>';
1057              }
1058              fwrite( $file_handle, $modified_line );
1059              if ( $modified_line == '?>' ) {
1060                  break;
1061              }
1062          }
1063  
1064          // Close the config file
1065          fclose( $file_handle );
1066  
1067          @chmod( $file_target, 0666 );
1068  
1069          return 1;
1070      }
1071  
1072      /**
1073       * Reports whether the request method is post or not
1074       *
1075       * @return boolean True if the page was posted, otherwise false
1076       */
1077  	function is_posted()
1078      {
1079          if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) ) {
1080              return true;
1081          }
1082          return false;
1083      }
1084  
1085      /**
1086       * Determines which step the installer is on based on user input
1087       *
1088       * @return boolean Always returns true
1089       **/
1090  	function set_step()
1091      {
1092          if ( $this->is_posted() ) {
1093              switch ( $this->step ) {
1094                  case 1:
1095                      $this->set_language();
1096                      if ( $_POST['forward_0_0'] ) {
1097                          $this->stop_process = 1;
1098                      }
1099                      break;
1100  
1101                  case 2:
1102                      if ( $_POST['forward_1_2'] ) {
1103                          $this->stop_process = 1;
1104                      }
1105                      break;
1106  
1107                  case 3:
1108                      // If this is actually a request to go back to step 2
1109                      if ( $_POST['back_2_1'] ) {
1110                          $this->step = 2;
1111                          break;
1112                      }
1113  
1114                      // If we have come forward from step 2 then don't process form 3
1115                      if ( $_POST['forward_2_1'] ) {
1116                          $this->stop_process = true;
1117                      }
1118  
1119                      // Determine what the status of the previous step was based on input
1120                      if ( $_POST['toggle_2_0'] ) {
1121                          $this->strings[2]['status'] = __( '&laquo; completed' );
1122                          $this->step_status[2] = 'complete';
1123                      }
1124                      break;
1125  
1126                  case 4:
1127                      // Determine what the status of the previous step was based on input
1128                      if ( $_POST['toggle_2_0'] ) {
1129                          $this->strings[2]['status'] = __( '&laquo; completed' );
1130                          $this->step_status[2] = 'complete';
1131                      }
1132  
1133                      // If this is actually a request to go back to step 3
1134                      if ( $_POST['back_3_1'] ) {
1135                          $this->step = 3;
1136                          break;
1137                      }
1138  
1139                      // We have to have come forward from step 3
1140                      if ( $_POST['forward_3_1'] ) {
1141                          $this->strings[3]['status'] = __( '&laquo; completed' );
1142                          $this->step_status[3] = 'complete';
1143                      } else {
1144                          $this->step = 2;
1145                      }
1146                      break;
1147              }
1148          }
1149          return true;
1150      }
1151  
1152      /**
1153       * Sanitizes all data stored in the data array
1154       *
1155       * @return boolean Always returns true
1156       **/
1157  	function sanitize_form_data()
1158      {
1159          foreach ( $this->data as $step => $data ) {
1160              if ( isset( $data['form'] ) && is_array( $data['form'] ) ) {
1161                  foreach ( $data['form'] as $key => $value ) {
1162                      $this->data[$step]['form'][$key]['value'] = esc_attr( $value['value'] );
1163                  }
1164              }
1165          }
1166          return true;
1167      }
1168  
1169      /**
1170       * Directs processing of the form data based on the current step
1171       *
1172       * @return boolean Always returns true
1173       **/
1174  	function process_form()
1175      {
1176          if ( $this->is_posted() && !$this->stop_process ) {
1177              switch ( $this->step ) {
1178                  case 1:
1179                      $this->process_form_config_file();
1180                      break;
1181  
1182                  case 2:
1183                      $this->process_form_wordpress_integration();
1184                      break;
1185  
1186                  case 3:
1187                      $this->process_form_site_options();
1188                      break;
1189  
1190                  case 4:
1191                      $this->process_form_finalise_installation();
1192                      break;
1193              }
1194          }
1195          return true;
1196      }
1197  
1198      /**
1199       * Takes inputted form data and injects it into the data array
1200       *
1201       * @param integer $step Which steps data to process
1202       * @return boolean Always returns true
1203       **/
1204  	function inject_form_values_into_data( $step )
1205      {
1206          $data =& $this->data[$step]['form'];
1207  
1208          foreach ( $data as $key => $value ) {
1209              if ( 'forward_' !== substr( $key, 0, 8 ) && 'back_' !== substr( $key, 0, 5 ) ) {
1210                  if ( isset( $data[$key]['prerequisite'] ) && !$_POST[$data[$key]['prerequisite']] ) {
1211                      if ( isset( $data[$key]['default_value'] ) ) {
1212                          $data[$key]['value'] = $data[$key]['default_value'];
1213                      }
1214                      // do nothing - keep the default value
1215                  } else {
1216                      $data[$key]['value'] = stripslashes_deep( trim( $_POST[$key] ) );
1217                  }
1218              }
1219          }
1220  
1221          return true;
1222      }
1223  
1224      /**
1225       * Validates the supplied config file data and writes it to the config file.
1226       *
1227       * @return void
1228       **/
1229  	function process_form_config_file()
1230      {
1231          $this->inject_form_values_into_data( 1 );
1232  
1233          $data =& $this->data[1]['form'];
1234          
1235          if ( 'en_US' == $data['bb_lang']['value'] ) {
1236              $data['bb_lang']['value'] = '';
1237          }
1238  
1239          if ( $data['toggle_1']['value'] ) {
1240              $data['toggle_1']['checked'] = 'checked="checked"';
1241              $data['toggle_1']['display'] = 'block';
1242  
1243              // Deal with slashes in the keys
1244              //$data['bb_auth_key']['value']        = addslashes( stripslashes( $data['bb_auth_key']['value'] ) );
1245              //$data['bb_secure_auth_key']['value'] = addslashes( stripslashes( $data['bb_secure_auth_key']['value'] ) );
1246              //$data['bb_logged_in_key']['value']   = addslashes( stripslashes( $data['bb_logged_in_key']['value'] ) );
1247              //$data['bb_nonce_key']['value']       = addslashes( stripslashes( $data['bb_nonce_key']['value'] ) );
1248          }
1249  
1250          $requested_prefix = $data['bb_table_prefix']['value'];
1251          $data['bb_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['bb_table_prefix']['value'] );
1252          if ( $requested_prefix !== $data['bb_table_prefix']['value'] ) {
1253              $data['toggle_1']['checked'] = 'checked="checked"';
1254              $data['toggle_1']['display'] = 'block';
1255              $this->step_status[1] = 'incomplete';
1256              $this->strings[1]['messages']['error'][] = __( 'The table prefix can only contain letters, numbers and underscores.<br />Please review the suggestion below.' );
1257              $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; Based on your input the following prefix is suggested.' );
1258              return 'incomplete';
1259          }
1260          if ( empty( $data['bb_table_prefix']['value'] ) ) {
1261              $data['bb_table_prefix']['value'] = 'bb_';
1262              $data['toggle_1']['checked'] = 'checked="checked"';
1263              $data['toggle_1']['display'] = 'block';
1264              $this->step_status[1] = 'incomplete';
1265              $this->strings[1]['messages']['error'][] = __( 'The table prefix can not be blank.<br />Please review the suggestion below.' );
1266              $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; The default prefix has been inserted.' );
1267              return 'incomplete';
1268          }
1269  
1270          // Stop here if we are going backwards
1271          if ( $_POST['back_1_1'] ) {
1272              $this->step_status[1] = 'incomplete';
1273              return 'incomplete';
1274          }
1275  
1276          // Test the db connection.
1277          define( 'BBDB_NAME',     $data['bbdb_name']['value'] );
1278          define( 'BBDB_USER',     $data['bbdb_user']['value'] );
1279          define( 'BBDB_PASSWORD', $data['bbdb_password']['value'] );
1280          define( 'BBDB_HOST',     $data['bbdb_host']['value'] );
1281          define( 'BBDB_CHARSET',  $data['bbdb_charset']['value'] );
1282          define( 'BBDB_COLLATE',  $data['bbdb_collate']['value'] );
1283  
1284          // We'll fail here if the values are no good.
1285          require_once( BACKPRESS_PATH . 'class.bpdb-multi.php' );
1286  
1287          $bbdb = new BPDB_Multi( array(
1288              'name'     => BBDB_NAME,
1289              'user'     => BBDB_USER,
1290              'password' => BBDB_PASSWORD,
1291              'host'     => BBDB_HOST,
1292              'charset'  => defined( 'BBDB_CHARSET' ) ? BBDB_CHARSET : false,
1293              'collate'  => defined( 'BBDB_COLLATE' ) ? BBDB_COLLATE : false,
1294              'errors'   => 'suppress'
1295          ) );
1296  
1297          if ( !$bbdb->db_connect( 'SHOW TABLES;' ) ) {
1298              $bbdb->suppress_errors( false );
1299              $this->step_status[1] = 'incomplete';
1300              $this->strings[1]['messages']['error'][] = __( 'There was a problem connecting to the database you specified.<br />Please check the settings, then try again.' );
1301              return 'error';
1302          }
1303          $bbdb->suppress_errors( false );
1304  
1305          $config_result = $this->write_lines_to_file(
1306              BB_PATH . 'bb-config-sample.php',
1307              BB_PATH . 'bb-config.php',
1308              array(
1309                  "define( 'BBDB_NAME',"  => array( "'bbpress'",                     "'" . $data['bbdb_name']['value'] . "'" ),
1310                  "define( 'BBDB_USER',"  => array( "'username'",                    "'" . $data['bbdb_user']['value'] . "'" ),
1311                  "define( 'BBDB_PASSWO"  => array( "'password'",                    "'" . $data['bbdb_password']['value'] . "'" ),
1312                  "define( 'BBDB_HOST',"  => array( "'localhost'",                   "'" . $data['bbdb_host']['value'] . "'" ),
1313                  "define( 'BBDB_CHARSE"  => array( "'utf8'",                        "'" . $data['bbdb_charset']['value'] . "'" ),
1314                  "define( 'BBDB_COLLAT"  => array( "''",                            "'" . $data['bbdb_collate']['value'] . "'" ),
1315                  //"define( 'BB_AUTH_KEY"  => array( "'put your unique phrase here'", "'" . $data['bb_auth_key']['value'] . "'" ),
1316                  //"define( 'BB_SECURE_A"  => array( "'put your unique phrase here'", "'" . $data['bb_secure_auth_key']['value'] . "'" ),
1317                  //"define( 'BB_LOGGED_I"  => array( "'put your unique phrase here'", "'" . $data['bb_logged_in_key']['value'] . "'" ),
1318                  //"define( 'BB_NONCE_KE"  => array( "'put your unique phrase here'", "'" . $data['bb_nonce_key']['value'] . "'" ),
1319                  "\$bb_table_prefix = '" => array( "'bb_'",                         "'" . $data['bb_table_prefix']['value'] . "'" ),
1320                  "define( 'BB_LANG', '"  => array( "''",                            "'" . $data['bb_lang']['value'] . "'" )
1321              )
1322          );
1323  
1324          switch ( $config_result ) {
1325              case -1:
1326                  $this->step_status[1] = 'error';
1327                  $this->strings[1]['messages']['error'][] = __( 'I could not find the file <code>bb-config-sample.php</code><br />Please upload it to the root directory of your bbPress installation.' );
1328                  return 'error';
1329                  break;
1330              case 1:
1331                  $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
1332                  $this->step_status[1] = 'complete';
1333                  $this->strings[1]['messages']['message'][] = __( 'Your settings have been saved to the file <code>bb-config.php</code><br />You can now continue to the next step.' );
1334                  break;
1335              default:
1336                  // Just write the contents to screen
1337                  $this->data[1]['form']['config']['value'] = $config_result;
1338  
1339                  $this->step_status[1] = 'manual';
1340                  $this->strings[1]['messages']['error'][] = __( 'Your settings could not be saved to a configuration file. You will need to save the text shown below into a file named <code>bb-config.php</code> in the root directory of your bbPress installation before you can continue.' );
1341                  break;
1342          }
1343      }
1344  
1345      /**
1346       * Validates the WordPress integration settings
1347       *
1348       * @return void
1349       **/
1350  	function process_form_wordpress_integration()
1351      {
1352          // Check the referer
1353          bb_check_admin_referer( 'bbpress-installer' );
1354  
1355          $this->inject_form_values_into_data( 2 );
1356  
1357          $data =& $this->data[2]['form'];
1358  
1359          // If there are no settings then goto step 3
1360          if ( !$data['toggle_2_0']['value'] && !$_POST['back_2_1'] ) {
1361              $this->step_status[2] = 'complete';
1362              $this->strings[2]['messages']['message'][] = __( 'You have chosen to skip the WordPress integration step. You can always integrate WordPress later from within the admin area of bbPress.' );
1363              return 'complete';
1364          }
1365  
1366          // If integration is selected
1367          if ( $data['toggle_2_0']['value'] ) {
1368              $data['toggle_2_0']['checked'] = 'checked="checked"';
1369              $data['toggle_2_0']['display'] = 'block';
1370              $data['forward_2_0']['value'] = $data['toggle_2_0']['toggle_value']['on_value'];
1371  
1372              if ( $data['toggle_2_1']['value'] ) {
1373                  $data['toggle_2_1']['checked'] = 'checked="checked"';
1374                  $data['toggle_2_1']['display'] = 'block';
1375  
1376                  // Check the wp_siteurl URL for errors
1377                  $data['wp_siteurl']['value'] = $data['wp_siteurl']['value'] ? rtrim( $data['wp_siteurl']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1378                  $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $data['wp_siteurl']['value'] ) ? 'empty' : false;
1379                  if ( $parsed = parse_url( $data['wp_siteurl']['value'] ) ) {
1380                      $this->strings[2]['form_errors']['wp_siteurl'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1381                      $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1382                  } else {
1383                      $this->strings[2]['form_errors']['wp_siteurl'][] = 'urlparse';
1384                  }
1385  
1386                  // Check the wp_home URL for errors
1387                  $data['wp_home']['value'] = $data['wp_home']['value'] ? rtrim( $data['wp_home']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1388                  $this->strings[2]['form_errors']['wp_home'][] = empty( $data['wp_home']['value'] ) ? 'empty' : false;
1389                  if ( $parsed = parse_url( $data['wp_home']['value'] ) ) {
1390                      $this->strings[2]['form_errors']['wp_home'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1391                      $this->strings[2]['form_errors']['wp_home'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1392                  } else {
1393                      $this->strings[2]['form_errors']['wp_home'][] = 'urlparse';
1394                  }
1395  
1396                  // Deal with slashes in the keys
1397                  $data['wp_auth_key']['value']         = addslashes( stripslashes( $data['wp_auth_key']['value'] ) );
1398                  $data['wp_auth_salt']['value']        = addslashes( stripslashes( $data['wp_auth_salt']['value'] ) );
1399                  $data['wp_secure_auth_key']['value']  = addslashes( stripslashes( $data['wp_secure_auth_key']['value'] ) );
1400                  $data['wp_secure_auth_salt']['value'] = addslashes( stripslashes( $data['wp_secure_auth_salt']['value'] ) );
1401                  $data['wp_logged_in_key']['value']    = addslashes( stripslashes( $data['wp_logged_in_key']['value'] ) );
1402                  $data['wp_logged_in_salt']['value']   = addslashes( stripslashes( $data['wp_logged_in_salt']['value'] ) );
1403  
1404                  // Check the keys for errors
1405                  $this->strings[2]['form_errors']['wp_auth_key'][]         = empty( $data['wp_auth_key']['value'] ) ? 'empty' : false;
1406                  $this->strings[2]['form_errors']['wp_secure_auth_key'][]  = empty( $data['wp_secure_auth_key']['value'] ) ? 'empty' : false;
1407                  $this->strings[2]['form_errors']['wp_logged_in_key'][]    = empty( $data['wp_logged_in_key']['value'] ) ? 'empty' : false;
1408  
1409                  // Salts can be taken from the database if specified
1410                  if ( !$data['toggle_2_2']['value'] ) {
1411                      $this->strings[2]['form_errors']['wp_auth_salt'][]        = empty( $data['wp_auth_salt']['value'] ) ? 'empty' : false;
1412                      // NB; secure_auth_salt is not always set in WordPress
1413                      $this->strings[2]['form_errors']['wp_logged_in_salt'][]   = empty( $data['wp_logged_in_salt']['value'] ) ? 'empty' : false;
1414                  }
1415              }
1416  
1417              // If database integration is selected
1418              if ( $data['toggle_2_2']['value'] ) {
1419                  $data['toggle_2_2']['checked'] = 'checked="checked"';
1420                  $data['toggle_2_2']['display'] = 'block';
1421  
1422                  // Make the wp_table_prefix valid
1423                  $data['wp_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['wp_table_prefix']['value'] );
1424                  $data['wp_table_prefix']['value'] = empty( $data['wp_table_prefix']['value'] ) ? 'wp_' : $data['wp_table_prefix']['value'];
1425  
1426                  // Make the wordpress_mu_primary_blog_id valid
1427                  $data['wordpress_mu_primary_blog_id']['value'] = preg_replace( '/[^0-9]/', '', $data['wordpress_mu_primary_blog_id']['value'] );
1428  
1429                  // If advanced database integration is selected
1430                  if ( $data['toggle_2_3']['value'] ) {
1431                      $data['toggle_2_3']['checked'] = 'checked="checked"';
1432                      $data['toggle_2_3']['display'] = 'block';
1433                  }
1434              }
1435  
1436              if ( !$data['toggle_2_1']['value'] && !$data['toggle_2_2']['value'] ) {
1437                  $this->step_status[2] = 'incomplete';
1438                  $this->strings[2]['messages']['error'][] = __( 'You must enter your settings for integration setup to complete. Choose which integration settings you wish to enter from the options below.' );
1439                  $this->strings[2]['form_errors']['toggle_2_1'][] = true;
1440                  $this->strings[2]['form_errors']['toggle_2_2'][] = true;
1441                  return 'incomplete';
1442              }
1443  
1444              // Remove empty values from the error array
1445              foreach ( $this->strings[2]['form_errors'] as $input => $types) {
1446                  $types = array_filter( $types);
1447                  if ( !count( $types ) ) {
1448                      unset( $this->strings[2]['form_errors'][$input] );
1449                  }
1450              }
1451  
1452              // Check for errors and build error messages
1453              if ( count( $this->strings[2]['form_errors'] ) ) {
1454  
1455                  $this->step_status[2] = 'incomplete';
1456                  $this->strings[2]['messages']['error'][] = __( 'Your integration settings have not been processed due to errors with the items marked below.' );
1457  
1458                  foreach ( $this->strings[2]['form_errors'] as $input => $types ) {
1459                      $errors = array();
1460  
1461                      foreach ( $types as $type ) {
1462                          switch ( $type ) {
1463                              case 'empty':
1464                                  // Only return this error when empty
1465                                  $errors = array( __( '&bull; This value is required to continue.' ) );
1466                                  break(2);
1467                              case 'urlparse':
1468                                  $errors[] = __( '&bull; This does not appear to be a valid URL.' );
1469                                  break;
1470                              case 'urlscheme':
1471                                  $errors[] = __( '&bull; The URL must begin with "http" or "https".' );
1472                                  break;
1473                              case 'urlhost':
1474                                  $errors[] = __( '&bull; The URL does not contain a host name.' );
1475                                  break;
1476                          }
1477                      }
1478  
1479                      $this->strings[2]['form_errors'][$input] = $errors;
1480                  }
1481  
1482                  return 'incomplete';
1483              }
1484  
1485              // If database integration is selected
1486              if ( $data['toggle_2_2']['value'] ) {
1487  
1488                  // Test the db connection.
1489  
1490                  // Setup variables and constants if available
1491                  global $bb;
1492                  $bb->wp_table_prefix = $data['wp_table_prefix']['value'];
1493                  if ( $data['toggle_2_3']['value'] ) {
1494                      // These may be empty at this particular stage
1495                      if ( !empty( $data['user_bbdb_name']['value'] ) ) {
1496                          $bb->user_bbdb_name = $data['user_bbdb_name']['value'];
1497                      }
1498                      if ( !empty( $data['user_bbdb_user']['value'] ) ) {
1499                          $bb->user_bbdb_user = $data['user_bbdb_user']['value'];
1500                      }
1501                      if ( !empty( $data['user_bbdb_password']['value'] ) ) {
1502                          $bb->user_bbdb_password = $data['user_bbdb_password']['value'];
1503                      }
1504                      if ( !empty( $data['user_bbdb_host']['value'] ) ) {
1505                          $bb->user_bbdb_host = $data['user_bbdb_host']['value'];
1506                      }
1507                      if ( !empty( $data['user_bbdb_charset']['value'] ) ) {
1508                          $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $data['user_bbdb_charset']['value'] );
1509                      }
1510                      if ( !empty( $data['user_bbdb_collate']['value'] ) ) {
1511                          $bb->user_bbdb_collate = preg_replace( '/[^a-z0-9_-]/i', '', $data['user_bbdb_collate']['value'] );
1512                      }
1513                      if ( !empty( $data['custom_user_table']['value'] ) ) {
1514                          $bb->custom_user_table = preg_replace( '/[^a-z0-9_-]/i', '', $data['custom_user_table']['value'] );
1515                      }
1516                      if ( !empty( $data['custom_user_meta_table']['value'] ) ) {
1517                          $bb->custom_user_meta_table = preg_replace( '/[^a-z0-9_-]/i', '', $data['custom_user_meta_table']['value'] );
1518                      }
1519                  }
1520  
1521                  // Bring in the database object
1522                  global $bbdb;
1523                  global $bb_table_prefix;
1524  
1525                  // Resolve the custom user tables for bpdb
1526                  bb_set_custom_user_tables();
1527  
1528                  if ( isset( $bb->custom_databases) && isset( $bb->custom_databases['user'] ) ) {
1529                      $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
1530                  }
1531  
1532                  // Add custom tables if required
1533                  if ( isset( $bb->custom_tables['users'] ) || isset( $bb->custom_tables['usermeta'] ) ) {
1534                      $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
1535                      if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) ) {
1536                          die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
1537                      }
1538                  }
1539  
1540                  // Hide errors for the test
1541                  $bbdb->hide_errors();
1542  
1543                  $result = $bbdb->query( 'DESCRIBE ' . $bbdb->users . ';' );
1544                  $result_error = $bbdb->get_error();
1545  
1546                  // Select from the user table (may fail if there are no records in the table)
1547                  if ( !$result && $result_error ) {
1548                      // We couldn't connect to the database at all
1549  
1550                      // Turn errors back on
1551                      $bbdb->show_errors();
1552  
1553                      // Set the status
1554                      $this->step_status[2] = 'incomplete';
1555                      if ( !empty( $data['user_bbdb_name']['value'] ) ) {
1556                          $this->strings[2]['form_errors']['user_bbdb_name'][] = true;
1557                      }
1558                      if ( !empty( $data['user_bbdb_user']['value'] ) ) {
1559                          $this->strings[2]['form_errors']['user_bbdb_user'][] = true;
1560                      }
1561                      if ( !empty( $data['user_bbdb_password']['value'] ) ) {
1562                          $this->strings[2]['form_errors']['user_bbdb_password'][] = true;
1563                      }
1564                      if ( !empty( $data['user_bbdb_host']['value'] ) ) {
1565                          $this->strings[2]['form_errors']['user_bbdb_host'][] = true;
1566                      }
1567                      if ( !empty( $data['custom_user_table']['value'] ) ) {
1568                          $this->strings[2]['form_errors']['custom_user_table'][] = true;
1569                      }
1570                      if ( !empty( $data['custom_user_meta_table']['value'] ) ) {
1571                          $this->strings[2]['form_errors']['custom_user_meta_table'][] = true;
1572                      }
1573                      $this->strings[2]['messages']['error'][] = __( 'There was a problem connecting to the WordPress user database you specified. Please check the settings, then try again.' );
1574                      return 'incomplete';
1575                  }
1576  
1577                  if ( $result_error ) {
1578                      // The result is an error, presumably telling us the table doesn't exist
1579  
1580                      // Turn errors back on
1581                      $bbdb->show_errors();
1582  
1583                      // Set the status
1584                      $this->step_status[2] = 'incomplete';
1585  
1586                      if ( $data['toggle_2_3']['value'] ) {
1587                          $this->strings[2]['messages']['error'][] = __( 'Existing WordPress user tables could not be found in the WordPress database you specified.' );
1588                      } else {
1589                          $this->strings[2]['messages']['error'][] = __( 'Existing WordPress user tables could not be found in the bbPress database you specified in step 1.<br /><br />This is probably because the database does not already contain working WordPress tables. You may need to specify advanced database settings or leave integration until after installation.' );
1590                      }
1591                      $this->strings[2]['form_errors']['wp_table_prefix'][] = __( '&bull; This may not be a valid user table prefix.' );
1592                      return 'incomplete';
1593                  }
1594  
1595                  // Turn errors back on
1596                  $bbdb->show_errors();
1597              }
1598          }
1599  
1600          // Stop here if we are going backwards
1601          if ( $_POST['back_2_1'] ) {
1602              $this->step_status[2] = 'incomplete';
1603              return 'incomplete';
1604          }
1605  
1606          // If we make it this may we are complete, so set the status to complete
1607          $this->step_status[2] = 'complete';
1608          $this->strings[2]['messages']['message'][] = __( 'Your WordPress integration cookie and database settings have been successfully validated. They will be saved after the next step.<br /><br />Once you have finished installing, you should visit the WordPress integration section of the bbPress admin area for further options and integration instructions, including user mapping and the correct cookie settings to add to your WordPress configuration file.' );
1609          return 'complete';
1610      }
1611  
1612      /**
1613       * Validates the site options.
1614       *
1615       * @return void
1616       **/
1617  	function process_form_site_options()
1618      {
1619          // Check the referer
1620          bb_check_admin_referer( 'bbpress-installer' );
1621  
1622          $this->inject_form_values_into_data( 2 );
1623          $this->inject_form_values_into_data( 3 );
1624  
1625          $data =& $this->data[3]['form'];
1626  
1627          $this->strings[3]['form_errors']['name'][] = empty( $data['name']['value'] ) ? 'empty' : false;
1628  
1629          $data['uri']['value'] = $data['uri']['value'] ? rtrim( $data['uri']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
1630          $this->strings[3]['form_errors']['uri'][] = empty( $data['uri']['value'] ) ? 'empty' : false;
1631          if ( $parsed = parse_url( $data['uri']['value'] ) ) {
1632              $this->strings[3]['form_errors']['uri'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
1633              $this->strings[3]['form_errors']['uri'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
1634          } else {
1635              $this->strings[3]['form_errors']['uri'][] = 'urlparse';
1636          }
1637  
1638          $this->strings[3]['form_errors']['keymaster_user_login'][] = empty( $data['keymaster_user_login']['value'] ) ? 'empty' : false;
1639          if ( $data['keymaster_user_login']['value'] != sanitize_user( $data['keymaster_user_login']['value'], true ) ) {
1640              $this->strings[3]['form_errors']['keymaster_user_login'][] = 'userlogin';
1641          }
1642          $data['keymaster_user_login']['value'] = sanitize_user( $data['keymaster_user_login']['value'], true );
1643  
1644          // Check for a valid email
1645          $this->strings[3]['form_errors']['keymaster_user_email'][] = empty( $data['keymaster_user_email']['value'] ) ? 'empty' : false;
1646          $this->strings[3]['form_errors']['keymaster_user_email'][] = !is_email( $data['keymaster_user_email']['value'] ) ? 'email' : false;
1647  
1648          // Check for a forum name
1649          if ( !$this->database_tables_are_installed() ) {
1650              $this->strings[3]['form_errors']['forum_name'][] = empty( $data['forum_name']['value'] ) ? 'empty' : false;
1651          }
1652  
1653          // Remove empty values from the error array
1654          foreach ( $this->strings[3]['form_errors'] as $input => $types ) {
1655              $types = array_filter( $types );
1656              if ( !count( $types ) ) {
1657                  unset( $this->strings[3]['form_errors'][$input] );
1658              }
1659          }
1660  
1661          // Check for errors and build error messages
1662          if ( count( $this->strings[3]['form_errors'] ) ) {
1663  
1664              $this->step_status[3] = 'incomplete';
1665              $this->strings[3]['messages']['error'][] = __( 'Your site settings have not been processed due to errors with the items marked below.' );
1666  
1667              foreach ( $this->strings[3]['form_errors'] as $input => $types ) {
1668                  $errors = array();
1669  
1670                  foreach ( $types as $type ) {
1671                      switch ( $type ) {
1672                          case 'empty':
1673                              // Only return this error when empty
1674                              $errors = array( __( '&bull; This value is required to continue.' ) );
1675                              break(2);
1676                          case 'urlparse':
1677                              $errors[] = __( '&bull; This does not appear to be a valid URL.' );
1678                              break;
1679                          case 'urlscheme':
1680                              $errors[] = __( '&bull; The URL must begin with "http" or "https".' );
1681                              break;
1682                          case 'urlhost':
1683                              $errors[] = __( '&bull; The URL does not contain a host name.' );
1684                              break;
1685                          case 'userlogin':
1686                              $errors[] = __( '&bull; Contains disallowed characters which have been removed.' );
1687                              break;
1688                          case 'email':
1689                              $errors[] = __( '&bull; The user email address appears to be invalid.' );
1690                              break;
1691                      }
1692                  }
1693  
1694                  $this->strings[3]['form_errors'][$input] = $errors;
1695              }
1696  
1697              return 'incomplete';
1698          }
1699  
1700          // Stop here if we are going backwards
1701          if ( $_POST['back_3_1'] ) {
1702              $this->step_status[3] = 'incomplete';
1703              return 'incomplete';
1704          }
1705  
1706          // If we make it this far we are good to go
1707          $this->step_status[3] = 'complete';
1708          $this->strings[3]['messages']['message'][] = __( 'Your site settings have been saved and we are now ready to complete the installation. So what are you waiting for?' );
1709          return 'complete';
1710      }
1711  
1712      /**
1713       * Finalises the installation by creating the database and writing all the supplied data to the database.
1714       *
1715       * @return void
1716       **/
1717  	function process_form_finalise_installation()
1718      {
1719          require_once( BB_PATH . 'bb-admin/includes/functions.bb-upgrade.php' );
1720          require_once ( BB_PATH . 'bb-admin/includes/functions.bb-admin.php' );
1721  
1722          $this->inject_form_values_into_data( 2 );
1723          $this->inject_form_values_into_data( 3 );
1724  
1725          $data2 =& $this->data[2]['form'];
1726          $data3 =& $this->data[3]['form'];
1727          $data4 =& $this->data[4]['form'];
1728  
1729          $error_log = array();
1730          $installation_log = array();
1731  
1732          // Check the referer
1733          bb_check_admin_referer( 'bbpress-installer' );
1734          $installation_log[] = __( 'Referrer is OK, beginning installation&hellip;' );
1735  
1736          global $bbdb;
1737  
1738          // Setup user table variables and constants if available
1739          if ( $data2['toggle_2_2']['value'] ) {
1740  
1741              $installation_log[] = '>>> ' . __( 'Setting up custom user table constants' );
1742  
1743              global $bb;
1744              global $bb_table_prefix;
1745  
1746              if ( !empty( $data2['wp_table_prefix']['value'] ) ) {
1747                  $bb->wp_table_prefix = $data2['wp_table_prefix']['value'];
1748              }
1749              if ( !empty( $data2['user_bbdb_name']['value'] ) ) {
1750                  $bb->user_bbdb_name = $data2['user_bbdb_name']['value'];
1751              }
1752              if ( !empty( $data2['user_bbdb_user']['value'] ) ) {
1753                  $bb->user_bbdb_user = $data2['user_bbdb_user']['value'];
1754              }
1755              if ( !empty( $data2['user_bbdb_password']['value'] ) ) {
1756                  $bb->user_bbdb_password = $data2['user_bbdb_password']['value'];
1757              }
1758              if ( !empty( $data2['user_bbdb_host']['value'] ) ) {
1759                  $bb->user_bbdb_host = $data2['user_bbdb_host']['value'];
1760              }
1761              if ( !empty( $data2['user_bbdb_charset']['value'] ) ) {
1762                  $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $data2['user_bbdb_charset']['value'] );
1763              }
1764              if ( !empty( $data2['user_bbdb_collate']['value'] ) ) {
1765                  $bb->user_bbdb_collate = preg_replace( '/[^a-z0-9_-]/i', '', $data2['user_bbdb_collate']['value'] );
1766              }
1767  
1768              bb_set_custom_user_tables();
1769  
1770              // Add custom user database if required
1771              if ( isset( $bb->custom_databases['user'] ) ) {
1772                  $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
1773              }
1774  
1775              // Add custom tables if required
1776              if ( isset( $bb->custom_tables ) ) {
1777                  $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
1778                  if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) )
1779                      die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
1780              }
1781          }
1782  
1783          // Create the database
1784          $installation_log[] = "\n" . __( 'Step 1 - Creating database tables' );
1785  
1786          if ( !$this->database_tables_are_installed() ) {
1787              // Hide db errors
1788              $bbdb->hide_errors();
1789              // Install the database
1790              $alterations = bb_install();
1791              // Show db errors
1792              $bbdb->show_errors();
1793  
1794              if ( isset( $alterations['errors'] ) && is_array( $alterations['errors'] ) ) {
1795                  $error_log = array_merge( $error_log, $alterations['errors'] );
1796              }
1797              if ( isset( $alterations['messages'] ) && is_array( $alterations['messages'] ) ) {
1798                  $installation_log = array_merge( $installation_log, $alterations['messages'] );
1799              }
1800  
1801              if ( !$this->database_tables_are_installed() ) {
1802                  $installation_log[] = '>>> ' . __( 'Database installation failed!!!' );
1803                  $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
1804                  $error_log[] = __( 'Database installation failed!!!' );
1805  
1806                  $this->step_status[4] = 'incomplete';
1807                  $this->strings[4]['h2'] = __( 'Installation failed!' );
1808                  $this->strings[4]['messages']['error'][] = __( 'The database failed to install. You may need to replace bbPress with a fresh copy and start again.' );
1809  
1810                  $data4['installation_log']['value'] = join( "\n", $installation_log );
1811                  $data4['error_log']['value'] = join( "\n", $error_log );
1812  
1813                  return 'incomplete';
1814              }
1815          } else {
1816              $installation_log[] = '>>> ' . __( 'Database is already installed!!!' );
1817          }
1818  
1819          // Integration settings passed from step 2
1820          // These are already validated provided that the referer checks out
1821          $installation_log[] = "\n" . __( 'Step 2 - WordPress integration (optional)' );
1822          if ( $data2['toggle_2_0']['value'] ) {
1823              if ( $data2['toggle_2_1']['value'] ) {
1824                  bb_update_option( 'wp_siteurl', $data2['wp_siteurl']['value'] );
1825                  $installation_log[] = '>>> ' . __( 'WordPress address (URL):' ) . ' ' . $data2['wp_siteurl']['value'];
1826  
1827                  bb_update_option( 'wp_home', $data2['wp_home']['value'] );
1828                  $installation_log[] = '>>> ' . __( 'Blog address (URL):' ) . ' ' . $data2['wp_home']['value'];
1829  
1830                  $config_result = $this->write_lines_to_file(
1831                      BB_PATH . 'bb-config.php',
1832                      false,
1833                      array(
1834                          "define( 'BB_AUTH_KEY"  => array( "'" . BB_AUTH_KEY . "'",        "'" . $data2['wp_auth_key']['value'] . "'" ),
1835                          "define( 'BB_SECURE_A"  => array( "'" . BB_SECURE_AUTH_KEY . "'", "'" . $data2['wp_secure_auth_key']['value'] . "'" ),
1836                          "define( 'BB_LOGGED_I"  => array( "'" . BB_LOGGED_IN_KEY . "'",   "'" . $data2['wp_logged_in_key']['value'] . "'" ),
1837                      )
1838                  );
1839  
1840                  switch ( $config_result ) {
1841                      case 1:
1842                          $installation_log[] = '>>> ' . __( 'WordPress cookie keys set.' );
1843                          break;
1844                      default:
1845                          $error_log[] = '>>> ' . __( 'WordPress cookie keys not set.' );
1846                          $error_log[] = '>>>>>> ' . __( 'Your "bb-config.php" file was not writable.' );
1847                          $error_log[] = '>>>>>> ' . __( 'You will need to manually re-define "BB_AUTH_KEY", "BB_SECURE_AUTH_KEY" and "BB_LOGGED_IN_KEY" in your "bb-config.php" file.' );
1848                          $installation_log[] = '>>> ' . __( 'WordPress cookie keys not set.' );
1849                          break;
1850                  }
1851  
1852                  if ( !empty( $data2['wp_auth_salt']['value'] ) ) {
1853                      bb_update_option( 'bb_auth_salt', $data2['wp_auth_salt']['value'] );
1854                      $installation_log[] = '>>> ' . __( 'WordPress "auth" cookie salt set from input.' );
1855                  }
1856  
1857                  if ( !empty( $data2['wp_secure_auth_salt']['value'] ) ) {
1858                      bb_update_option( 'bb_secure_auth_salt', $data2['wp_secure_auth_salt']['value'] );
1859                      $installation_log[] = '>>> ' . __( 'WordPress "secure auth" cookie salt set from input.' );
1860                  }
1861  
1862                  if ( !empty( $data2['wp_logged_in_salt']['value'] ) ) {
1863                      bb_update_option( 'bb_logged_in_salt', $data2['wp_logged_in_salt']['value'] );
1864                      $installation_log[] = '>>> ' . __( 'WordPress "logged in" cookie salt set from input.' );
1865                  }
1866              }
1867  
1868              if ( $data2['toggle_2_2']['value'] ) {
1869                  if (
1870                      !bb_get_option( 'bb_auth_salt' ) ||
1871                      !bb_get_option( 'bb_secure_auth_salt' ) ||
1872                      !bb_get_option( 'bb_logged_in_salt' )
1873                  ) {
1874                      $installation_log[] = '>>> ' . __( 'Fetching missing WordPress cookie salts.' );
1875  
1876                      $_prefix = $bb->wp_table_prefix;
1877                      if ( !empty( $data2['wordpress_mu_primary_blog_id']['value'] ) ) {
1878                          $_prefix .= $data2['wordpress_mu_primary_blog_id']['value'] . '_';
1879                      }
1880  
1881                      if ( isset( $bb->custom_databases['user'] ) ) {
1882                          $bbdb->tables['options'] = array( 'user', $_prefix . 'options' );
1883                      } else {
1884                          $bbdb->tables['options'] = $_prefix . 'options';
1885                      }
1886  
1887                      unset( $_prefix );
1888  
1889                      $bbdb->set_prefix( $bb_table_prefix );
1890  
1891                      if ( !bb_get_option( 'bb_auth_salt' ) ) {
1892                          $wp_auth_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'auth_salt' LIMIT 1" );
1893                          if ( $wp_auth_salt ) {
1894                              bb_update_option( 'bb_auth_salt', $wp_auth_salt );
1895                              $installation_log[] = '>>>>>> ' . __( 'WordPress "auth" cookie salt set.' );
1896                          } else {
1897                              $error_log[] = '>>> ' . __( 'WordPress "auth" cookie salt not set.' );
1898                              $error_log[] = '>>>>>> ' . __( 'Could not fetch "auth" cookie salt from the WordPress options table.' );
1899                              $error_log[] = '>>>>>> ' . __( 'You will need to manually define the "auth" cookie salt in your database.' );
1900                              $installation_log[] = '>>>>>> ' . __( 'WordPress "auth" cookie salt not set.' );
1901                          }
1902                      }
1903  
1904                      if ( !bb_get_option( 'bb_secure_auth_salt' ) ) {
1905                          $wp_secure_auth_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'secure_auth_salt' LIMIT 1" );
1906                          if ( $wp_secure_auth_salt ) {
1907                              bb_update_option( 'bb_secure_auth_salt', $wp_secure_auth_salt );
1908                              $installation_log[] = '>>>>>> ' . __( 'WordPress "secure auth" cookie salt set.' );
1909                          } else {
1910                              // This cookie salt is sometimes empty so don't error
1911                              $installation_log[] = '>>>>>> ' . __( 'WordPress "secure auth" cookie salt not set.' );
1912                          }
1913                      }
1914  
1915                      if ( !bb_get_option( 'bb_logged_in_salt' ) ) {
1916                          $wp_logged_in_salt = $bbdb->get_var( "SELECT `option_value` FROM $bbdb->options WHERE `option_name` = 'logged_in_salt' LIMIT 1" );
1917                          if ( $wp_logged_in_salt ) {
1918                              bb_update_option( 'bb_logged_in_salt', $wp_logged_in_salt );
1919                              $installation_log[] = '>>>>>> ' . __( 'WordPress "logged in" cookie salt set.' );
1920                          } else {
1921                              $error_log[] = '>>> ' . __( 'WordPress "logged in" cookie salt not set.' );
1922                              $error_log[] = '>>>>>> ' . __( 'Could not fetch "logged in" cookie salt from the WordPress options table.' );
1923                              $error_log[] = '>>>>>> ' . __( 'You will need to manually define the "logged in" cookie salt in your database.' );
1924                              $installation_log[] = '>>>>>> ' . __( 'WordPress "logged in" cookie salt not set.' );
1925                          }
1926                      }
1927                  }
1928  
1929                  if ( !empty( $data2['wp_table_prefix']['value'] ) ) {
1930                      bb_update_option( 'wp_table_prefix', $data2['wp_table_prefix']['value'] );
1931                      $installation_log[] = '>>> ' . __( 'User database table prefix:' ) . ' ' . $data2['wp_table_prefix']['value'];
1932                  }
1933  
1934                  if ( !empty( $data2['wordpress_mu_primary_blog_id']['value'] ) ) {
1935                      bb_update_option( 'wordpress_mu_primary_blog_id', $data2['wordpress_mu_primary_blog_id']['value'] );
1936                      $installation_log[] = '>>> ' . __( 'WordPress MU primary blog ID:' ) . ' ' . $data2['wordpress_mu_primary_blog_id']['value'];
1937                  }
1938  
1939                  if ( $data2['toggle_2_3']['value'] ) {
1940                      if ( !empty( $data2['user_bbdb_name']['value'] ) ) {
1941                          bb_update_option( 'user_bbdb_name', $data2['user_bbdb_name']['value'] );
1942                          $installation_log[] = '>>> ' . __( 'User database name:' ) . ' ' . $data2['user_bbdb_name']['value'];
1943                      }
1944                      if ( !empty( $data2['user_bbdb_user']['value'] ) ) {
1945                          bb_update_option( 'user_bbdb_user', $data2['user_bbdb_user']['value'] );
1946                          $installation_log[] = '>>> ' . __( 'User database user:' ) . ' ' . $data2['user_bbdb_user']['value'];
1947                      }
1948                      if ( !empty( $data2['user_bbdb_password']['value'] ) ) {
1949                          bb_update_option( 'user_bbdb_password', $data2['user_bbdb_password']['value'] );
1950                          $installation_log[] = '>>> ' . __( 'User database password:' ) . ' ' . $data2['user_bbdb_password']['value'];
1951                      }
1952                      if ( !empty( $data2['user_bbdb_host']['value'] ) ) {
1953                          bb_update_option( 'user_bbdb_host', $data2['user_bbdb_host']['value'] );
1954                          $installation_log[] = '>>> ' . __( 'User database host:' ) . ' ' . $data2['user_bbdb_host']['value'];
1955                      }
1956                      if ( !empty( $data2['user_bbdb_charset']['value'] ) ) {
1957                          bb_update_option( 'user_bbdb_charset', $data2['user_bbdb_charset']['value'] );
1958                          $installation_log[] = '>>> ' . __( 'User database character set:' ) . ' ' . $data2['user_bbdb_charset']['value'];
1959                      }
1960                      if ( !empty( $data2['user_bbdb_collate']['value'] ) ) {
1961                          bb_update_option( 'user_bbdb_collate', $data2['user_bbdb_collate']['value'] );
1962                          $installation_log[] = '>>> ' . __( 'User database collation:' ) . ' ' . $data2['user_bbdb_collate']['value'];
1963                      }
1964                      if ( !empty( $data2['custom_user_table']['value'] ) ) {
1965                          bb_update_option( 'custom_user_table', $data2['custom_user_table']['value'] );
1966                          $installation_log[] = '>>> ' . __( 'User database "user" table:' ) . ' ' . $data2['custom_user_table']['value'];
1967                      }
1968                      if ( !empty( $data2['custom_user_meta_table']['value'] ) ) {
1969                          bb_update_option( 'custom_user_meta_table', $data2['custom_user_meta_table']['value'] );
1970                          $installation_log[] = '>>> ' . __( 'User database "user meta" table:' ) . ' ' . $data2['custom_user_meta_table']['value'];
1971                      }
1972                  }
1973              }
1974          } else {
1975              $installation_log[] = '>>> ' . __( 'Integration not enabled' );
1976          }
1977  
1978          // Site settings passed from step 3
1979          // These are already validated provided that the referer checks out
1980          $installation_log[] = "\n" . __( 'Step 3 - Site settings' );
1981          bb_update_option( 'name', $data3['name']['value'] );
1982          $installation_log[] = '>>> ' . __( 'Site name:' ) . ' ' . $data3['name']['value'];
1983          bb_update_option( 'uri', $data3['uri']['value'] );
1984          $installation_log[] = '>>> ' . __( 'Site address (URL):' ) . ' ' . $data3['uri']['value'];
1985          bb_update_option( 'from_email', $data3['keymaster_user_email']['value'] );
1986          $installation_log[] = '>>> ' . __( 'From email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
1987  
1988          // Create the key master
1989          $keymaster_created = false;
1990  
1991          switch ( $data3['keymaster_user_type']['value'] ) {
1992              case 'new':
1993  
1994                  // Check to see if the user login already exists
1995                  if ( $keymaster_user = bb_get_user( $data3['keymaster_user_login']['value'], array( 'by' => 'login' ) ) ) {
1996                      // The keymaster is an existing bbPress user
1997                      $installation_log[] = '>>> ' . __( 'Key master could not be created!' );
1998                      $installation_log[] = '>>>>>> ' . __( 'That login is already taken!' );
1999                      $error_log[] = __( 'Key master could not be created!' );
2000  
2001                      if ( $keymaster_user->bb_capabilities['keymaster'] ) {
2002                          // The existing user is a key master - continue
2003                          $bb_current_user = bb_set_current_user( $keymaster_user->ID );
2004                          $installation_log[] = '>>>>>> ' . __( 'Existing key master entered!' );
2005                          $data4['keymaster_user_password']['value'] = __( 'Your bbPress password' );
2006                          $data3['keymaster_user_email']['value'] = $keymaster_user->user_email;
2007                          bb_update_option( 'from_email', $keymaster_user->user_email);
2008                          $installation_log[] = '>>>>>> ' . __( 'Re-setting admin email address.' );
2009                          $keymaster_created = true;
2010                      } else {
2011                          // The existing user is a non-key master user - halt installation
2012                          $installation_log[] = '>>>>>> ' . __( 'Existing user without key master role entered!' );
2013                          $installation_log[] = '>>>>>>>>> ' . __( 'Halting installation!' );
2014                          $this->step_status[4] = 'incomplete';
2015                          $this->strings[4]['h2'] = __( 'Installation failed!' );
2016                          $this->strings[4]['messages']['error'][] = __( 'The key master could not be created. An existing user was found with that user login.' );
2017  
2018                          $data4['installation_log']['value'] = join( "\n", $installation_log );
2019                          $data4['error_log']['value'] = join( "\n", $error_log );
2020  
2021                          return 'incomplete';
2022                      }
2023  
2024                      break;
2025                  }
2026  
2027                  // Helper function to let us know the password that was created
2028                  global $keymaster_password;
2029  				function bb_get_keymaster_password( $user_id, $pass ) {
2030                      global $keymaster_password;
2031                      $keymaster_password = $pass;
2032                  }
2033                  add_action( 'bb_new_user', 'bb_get_keymaster_password', 10, 2 );
2034  
2035                  // Create the new user (automattically given key master role when BB_INSTALLING is true)
2036                  if ( $keymaster_user_id = bb_new_user( $data3['keymaster_user_login']['value'], $data3['keymaster_user_email']['value'], '' ) ) {
2037                      $bb_current_user = bb_set_current_user( $keymaster_user_id );
2038                      $data4['keymaster_user_password']['value'] = $keymaster_password;
2039                      $installation_log[] = '>>> ' . __( 'Key master created' );
2040                      $installation_log[] = '>>>>>> ' . __( 'Username:' ) . ' ' . $data3['keymaster_user_login']['value'];
2041                      $installation_log[] = '>>>>>> ' . __( 'Email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
2042                      $installation_log[] = '>>>>>> ' . __( 'Password:' ) . ' ' . $data4['keymaster_user_password']['value'];
2043                      $keymaster_created = true;
2044                  } else {
2045                      $installation_log[] = '>>> ' . __( 'Key master could not be created!' );
2046                      $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
2047                      $error_log[] = __( 'Key master could not be created!' );
2048                      $this->step_status[4] = 'incomplete';
2049                      $this->strings[4]['h2'] = __( 'Installation failed!' );
2050                      $this->strings[4]['messages']['error'][] = __( 'The key master could not be created. You may need to replace bbPress with a fresh copy and start again.' );
2051  
2052                      $data4['installation_log']['value'] = join( "\n", $installation_log );
2053                      $data4['error_log']['value'] = join( "\n", $error_log );
2054  
2055                      return 'incomplete';
2056                  }
2057                  break;
2058  
2059              case 'old':
2060                  if ( $keymaster_user = bb_get_user( $data3['keymaster_user_login']['value'], array( 'by' => 'login' ) ) ) {
2061                      // The keymaster is an existing bbPress or WordPress user
2062                      $bb_current_user = bb_set_current_user( $keymaster_user->ID );
2063                      $bb_current_user->set_role( 'keymaster' );
2064                      $data4['keymaster_user_password']['value'] = __( 'Your existing password' );
2065                      $installation_log[] = '>>> ' . __( 'Key master role assigned to existing user' );
2066                      $installation_log[] = '>>>>>> ' . __( 'Username:' ) . ' ' . $data3['keymaster_user_login']['value'];
2067                      $installation_log[] = '>>>>>> ' . __( 'Email address:' ) . ' ' . $data3['keymaster_user_email']['value'];
2068                      $installation_log[] = '>>>>>> ' . __( 'Password:' ) . ' ' . $data4['keymaster_user_password']['value'];
2069                      $keymaster_created = true;
2070                  } else {
2071                      $installation_log[] = '>>> ' . __( 'Key master role could not be assigned to existing user!' );
2072                      $installation_log[] = '>>>>>> ' . __( 'Halting installation!' );
2073                      $error_log[] = __( 'Key master could not be created!' );
2074                      $this->step_status[4] = 'incomplete';
2075                      $this->strings[4]['h2'] = __( 'Installation failed!' );
2076                      $this->strings[4]['messages']['error'][] = __( 'The key master could not be assigned. You may need to replace bbPress with a fresh copy and start again.' );
2077  
2078                      $data4['installation_log']['value'] = join( "\n", $installation_log );
2079                      $data4['error_log']['value'] = join( "\n", $error_log );
2080  
2081                      return 'incomplete';
2082                  }
2083                  break;
2084          }
2085  
2086          // Don't create an initial forum if any forums already exist
2087          if (!$bbdb->get_results( 'SELECT `forum_id` FROM `' . $bbdb->forums . '` LIMIT 1;' ) ) {
2088              if ( $this->language != BB_LANG) {
2089                  global $locale, $l10n;
2090                  $locale = BB_LANG;
2091                  unset( $l10n['default'] );
2092                  bb_load_default_textdomain();
2093              }
2094  
2095              $description = __( 'Just another bbPress community' );
2096              bb_update_option( 'description', $description);
2097  
2098              if ( $this->language != BB_LANG) {
2099                  $locale = $this->language;
2100                  unset( $l10n['default'] );
2101                  bb_load_default_textdomain();
2102              }
2103  
2104              $installation_log[] = '>>> ' . __( 'Description:' ) . ' ' . $description;
2105  
2106              if ( $forum_id = bb_new_forum( array( 'forum_name' => $data3['forum_name']['value'] ) ) ) {
2107                  $installation_log[] = '>>> ' . __( 'Forum name:' ) . ' ' . $data3['forum_name']['value'];
2108  
2109                  if ( $this->language != BB_LANG) {
2110                      $locale = BB_LANG;
2111                      unset( $l10n['default'] );
2112                      bb_load_default_textdomain();
2113                  }
2114  
2115                  $topic_title = __( 'Your first topic' );
2116                  $topic_id = bb_insert_topic(
2117                      array(
2118                          'topic_title' => $topic_title,
2119                          'forum_id' => $forum_id,
2120                          'tags' => 'bbPress'
2121                      )
2122                  );
2123                  $post_text = __( 'First Post!  w00t.' );
2124                  bb_insert_post(
2125                      array(
2126                          'topic_id' => $topic_id,
2127                          'post_text' => $post_text
2128                      )
2129                  );
2130  
2131                  if ( $this->language != BB_LANG ) {
2132                      $locale = $this->language;
2133                      unset( $l10n['default'] );
2134                      bb_load_default_textdomain();
2135                  }
2136  
2137                  $installation_log[] = '>>>>>> ' . __( 'Topic:' ) . ' ' . $topic_title;
2138                  $installation_log[] = '>>>>>>>>> ' . __( 'Post:' ) . ' ' . $post_text;
2139              } else {
2140                  $installation_log[] = '>>> ' . __( 'Forum could not be created!' );
2141                  $error_log[] = __( 'Forum could not be created!' );
2142              }
2143          } else {
2144              $installation_log[] = '>>> ' . __( 'There are existing forums in this database.' );
2145              $installation_log[] = '>>>>>> ' . __( 'No new forum created.' );
2146              $error_log[] = __( 'Forums already exist!' );
2147          }
2148  
2149          if ( defined( 'BB_PLUGIN_DIR' ) && BB_PLUGIN_DIR && !file_exists( BB_PLUGIN_DIR ) ) {
2150              // Just suppress errors as this is not critical
2151              if ( @mkdir( BB_PLUGIN_DIR, 0755 ) ) {
2152                  $installation_log[] = '>>> ' . sprintf( __( 'Making plugin directory at %s.' ),  BB_PLUGIN_DIR );
2153              }
2154          }
2155  
2156          if ( defined( 'BB_THEME_DIR' ) && BB_THEME_DIR && !file_exists( BB_THEME_DIR ) ) {
2157              // Just suppress errors as this is not critical
2158              if ( @mkdir( BB_THEME_DIR, 0755 ) ) {
2159                  $installation_log[] = '>>> ' . sprintf( __( 'Making theme directory at %s.' ),  BB_THEME_DIR );
2160              }
2161          }
2162  
2163          if ( $keymaster_created ) {
2164              $keymaster_email_message = sprintf(
2165                  __( "Your new bbPress site has been successfully set up at:\n\n%1\$s\n\nYou can log in to the key master account with the following information:\n\nUsername: %2\$s\nPassword: %3\$s\n\nWe hope you enjoy your new forums. Thanks!\n\n--The bbPress Team\nhttp://bbpress.org/" ),
2166                  bb_get_uri( null, null, BB_URI_CONTEXT_TEXT ),
2167                  $data3['keymaster_user_login']['value'],
2168                  $data4['keymaster_user_password']['value']
2169              );
2170  
2171              if ( bb_mail( $data3['keymaster_user_email']['value'], __( 'New bbPress installation' ), $keymaster_email_message ) ) {
2172                  $installation_log[] = '>>> ' . __( 'Key master email sent' );
2173              } else {
2174                  $installation_log[] = '>>> ' . __( 'Key master email not sent!' );
2175                  $error_log[] = __( 'Key master email not sent!' );
2176              }
2177          }
2178  
2179          if ( count( $error_log ) ) {
2180              $this->strings[4]['h2'] = __( 'Installation completed with some errors!' );
2181              $this->strings[4]['messages']['error'][] = __( 'Your installation completed with some minor errors. See the error log below for more specific information.' );
2182              $installation_log[] = "\n" . __( 'There were some errors encountered during installation!' );
2183          } else {
2184              $this->strings[4]['messages']['message'][] = __( 'Your installation completed successfully.' );
2185              $installation_log[] = "\n" . __( 'Installation complete!' );
2186          }
2187  
2188          $this->step_status[4] = 'complete';
2189  
2190          $data4['installation_log']['value'] = join( "\n", $installation_log );
2191          $data4['error_log']['value'] = join( "\n", $error_log );
2192  
2193          return 'complete';
2194      }
2195  
2196      /**
2197       * Prints a text input form element.
2198       *
2199       * @param $key string The key of the data to populate the element with.
2200       * @param $direction string Optional. The text direction, only 'ltr' or 'rtl' are acceptable.
2201       * @return void
2202       **/
2203  	function input_text( $key, $direction = false )
2204      {
2205          $data = $this->data[$this->step]['form'][$key];
2206  
2207          $class = '';
2208          $classes = array();
2209          if ( isset( $data['note'] ) ) {
2210              $classes[] = 'has-note';
2211          }
2212          if ( isset( $data['label'] ) ) {
2213              $classes[] = 'has-label';
2214          }
2215  
2216          if ( isset( $this->data[$this->step]['form'][$key]['type'] ) ) {
2217              $type = $this->data[$this->step]['form'][$key]['type'];
2218          } else {
2219              $type = 'text';
2220          }
2221          $classes[] = 'for-input-' . $type;
2222  
2223          if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2224              $classes[] = 'error';
2225          }
2226          if ( count( $classes ) ) {
2227              $class = ' class="' . join( ' ', $classes ) . '"';
2228          }
2229  
2230          $r = "\t" . '<label id="label-' . esc_attr( $key ) . '" for="' . esc_attr( $key ) . '"' . $class . '>' . "\n";
2231  
2232          if ( isset( $data['label'] ) ) {
2233              $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2234          }
2235  
2236          if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2237              foreach ( $this->strings[$this->step]['form_errors'][$key] as $error ) {
2238                  if ( !is_bool( $error ) ) {
2239                      $r .= "\t\t" . '<span class="error">' . $error . '</span>' . "\n";
2240                  }
2241              }
2242          }
2243  
2244          if ( isset( $data['maxlength'] ) && is_integer( $data['maxlength'] ) ) {
2245              $maxlength = ' maxlength="' . esc_attr( $data['maxlength'] ) . '"';
2246          }
2247  
2248          if ( $direction && in_array( strtolower( $direction ), array( 'ltr', 'rtl' ) ) ) {
2249              $direction = ' dir="' . esc_attr( strtolower( $direction ) ) . '"';
2250          }
2251  
2252          if ( isset( $data['autocomplete'] ) ) {
2253              $autocomplete = ' autocomplete="' . esc_attr( $data['autocomplete'] ) . '"';
2254          } else {
2255              $autocomplete = '';
2256          }
2257  
2258          $this->tabindex++;
2259          $r .= "\t\t" . '<input' . $direction . ' type="' . esc_attr( $type ) . '" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" class="text' . $has_note_class . '" value="' . esc_attr( $data['value'] ) . '"' . $maxlength . $autocomplete . ' tabindex="' . $this->tabindex . '" />' . "\n";
2260  
2261          if ( isset( $data['note'] ) ) {
2262              $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2263              $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2264          }
2265  
2266          $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2267          $r .= "\t" . '</label>' . "\n";
2268  
2269          echo $r;
2270      }
2271  
2272      /**
2273       * Prints a hidden input form element.
2274       *
2275       * @param $key string The key of the data to populate the element with.
2276       * @return void
2277       **/
2278  	function input_hidden( $key )
2279      {
2280          $r = "\t" . '<input type="hidden" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" value="' . esc_attr( $this->data[$this->step]['form'][$key]['value'] ) . '" />' . "\n";
2281  
2282          echo $r;
2283      }
2284  
2285      /**
2286       * Prints a textarea form element.
2287       *
2288       * @param $key string The key of the data to populate the element with.
2289       * @param $direction string Optional. The text direction, only 'ltr' or 'rtl' are acceptable.
2290       * @return void
2291       **/
2292  	function textarea( $key, $direction = false)
2293      {
2294          $data = $this->data[$this->step]['form'][$key];
2295  
2296          $class = '';
2297          $classes = array( 'for-textarea' );
2298          if ( isset( $data['note'] ) ) {
2299              $classes[] = 'has-note';
2300          }
2301          if ( isset( $data['label'] ) ) {
2302              $classes[] = 'has-label';
2303          }
2304          if ( count( $classes ) ) {
2305              $class = ' class="' . join( ' ', $classes ) . '"';
2306          }
2307  
2308          $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2309  
2310          if ( isset( $data['label'] ) ) {
2311              $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2312          }
2313  
2314          if ( isset( $data['note'] ) ) {
2315              $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2316              $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2317          }
2318  
2319          if ( $direction && in_array( strtolower( $direction ), array( 'ltr', 'rtl' ) ) ) {
2320              $direction = ' dir="' . esc_attr( strtolower( $direction ) ) . '"';
2321          }
2322  
2323          $this->tabindex++;
2324          $r .= "\t\t" . '<textarea id="' . esc_attr( $key ) . '" rows="5" cols="30"' . $direction . ' tabindex="' . $this->tabindex . '">' . esc_html( $data['value'] ) . '</textarea>' . "\n";
2325  
2326          $r .= "\t" . '</label>' . "\n";
2327  
2328          echo $r;
2329      }
2330  
2331      /**
2332       * Prints a select form element populated with options.
2333       *
2334       * @param $key string The key of the data to populate the element with.
2335       * @return void
2336       **/
2337  	function select( $key )
2338      {
2339          $data = $this->data[$this->step]['form'][$key];
2340  
2341          $class = '';
2342          $classes = array( 'for-select' );
2343          if ( isset( $data['note'] ) ) {
2344              $classes[] = 'has-note';
2345          }
2346          if ( isset( $data['label'] ) ) {
2347              $classes[] = 'has-label';
2348          }
2349          if ( count( $classes ) ) {
2350              $class = ' class="' . join( ' ', $classes ) . '"';
2351          }
2352  
2353          $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2354  
2355          if ( isset( $data['label'] ) ) {
2356              $r .= "\t\t" . '<span>' . $data['label'] . '</span>' . "\n";
2357          }
2358  
2359          if ( isset( $data['options'] ) ) {
2360              $r .= "\t\t" . '<select id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '"';
2361              if ( isset( $data['onchange'] ) ) {
2362                  $r .= ' onchange="' . esc_attr( $data['onchange'] ) . '"';
2363              }
2364              $this->tabindex++;
2365              $r .= ' tabindex="' . $this->tabindex . '">' . "\n";
2366  
2367              foreach ( $data['options'] as $value => $display ) {
2368                  if ( $data['value'] == $value ) {
2369                      $selected = ' selected="selected"';
2370                  } else {
2371                      $selected = '';
2372                  }
2373  
2374                  $r .= "\t\t\t" . '<option value="' . esc_attr( $value ) . '"' . $selected . '>' . esc_html( $display ) . '</option>' . "\n";
2375              }
2376  
2377              $r .= "\t\t" . '</select>';
2378          }
2379  
2380          if ( isset( $data['note'] ) ) {
2381              $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2382              $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2383          }
2384  
2385          $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2386          $r .= "\t" . '</label>' . "\n";
2387  
2388          echo $r;
2389      }
2390  
2391      /**
2392       * Prints an appropriate language selection form element if there are any available.
2393       *
2394       * @return void
2395       **/
2396  	function select_language()
2397      {
2398          if ( count( $this->languages ) > 1 ) {
2399              $this->data[1]['form']['bb_lang']['value'] = $this->language;
2400              $this->data[1]['form']['bb_lang']['options'] = $this->languages;
2401              $this->select( 'bb_lang' );
2402          } else {
2403              $this->data[1]['form']['bb_lang']['value'] = 'en_US';
2404              $this->input_hidden( 'bb_lang' );
2405          }
2406      }
2407  
2408      /**
2409       * Prints an input checkbox which controls display of an optional section of settings.
2410       *
2411       * @param string $key The identifier of the area to be toggled.
2412       * @return void
2413       **/
2414  	function input_toggle( $key )
2415      {
2416          $data = $this->data[$this->step]['form'][$key];
2417  
2418          $class = '';
2419          $classes = array( 'for-toggle' );
2420          if ( isset( $data['note'] ) ) {
2421              $classes[] = 'has-note';
2422          }
2423          if ( isset( $data['label'] ) ) {
2424              $classes[] = 'has-label';
2425          }
2426  
2427          $onclick = 'toggleBlock(this, \'' . esc_js( $key . '_target' ) . '\' );';
2428          if ( isset( $data['toggle_value'] ) ) {
2429              $onclick .= ' toggleValue(this, \'' . esc_js( $data['toggle_value']['target'] ) . '\', \'' . esc_js( $data['toggle_value']['off_value'] ) . '\', \'' . esc_js( $data['toggle_value']['on_value'] ) . '\' );';
2430          }
2431  
2432          $checked = $data['checked'] ? ' ' . trim( $data['checked'] ) : '';
2433  
2434          if ( isset( $this->strings[$this->step]['form_errors'][$key] ) ) {
2435              $classes[] = 'error';
2436          }
2437          if ( count( $classes ) ) {
2438              $class = ' class="' . join( ' ', $classes ) . '"';
2439          }
2440  
2441          $r = "\t" . '<label id="label-' . esc_attr( $key ) . '"' . $class . ' for="' . esc_attr( $key ) . '">' . "\n";
2442  
2443          $r .= "\t\t" . '<span>' . "\n";
2444          $this->tabindex++;
2445          $r .= "\t\t\t" . '<input type="checkbox" id="' . esc_attr( $key ) . '" name="' . esc_attr( $key ) . '" class="checkbox" onclick="' . esc_attr( $onclick ) . '"' . $checked . ' value="1" tabindex="' . $this->tabindex . '" />' . "\n";
2446          if ( isset( $data['label'] ) ) {
2447              $r .= "\t\t\t" . $data['label'] . "\n";
2448          }
2449          $r .= "\t\t" . '</span>' . "\n";
2450  
2451          if ( isset( $data['note'] ) ) {
2452              $r .= "\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-' . esc_attr( $key ) . '\');">?</a>' . "\n";
2453              $r .= "\t\t" . '<p id="note-' . esc_attr( $key ) . '" class="note" style="display:none">' . $data['note'] . '</p>' . "\n";
2454          }
2455  
2456          $r .= "\t\t" . '<div class="clear"></div>' . "\n";
2457          $r .= "\t" . '</label>' . "\n";
2458  
2459          echo $r;
2460      }
2461  
2462      /**
2463       * Prints the input buttons which post each step and optionally go back a step.
2464       *
2465       * @param string $forward The HTML element ID of the forward button.
2466       * @param string $back Optional. The HTML element ID of the back button.
2467       * @return void
2468       **/
2469  	function input_buttons( $forward, $back = false, $step = false )
2470      {
2471          $data_back = $back ? $this->data[$this->step]['form'][$back] : false;
2472          $data_forward = $this->data[$this->step]['form'][$forward];
2473  
2474          $r = '<fieldset class="buttons">' . "\n";
2475  
2476          if ( !$step ) {
2477              $step = $this->step;
2478          }
2479          $r .= "\t" . '<input type="hidden" id="step" name="step" value="' . (int) $step . '" />' . "\n";
2480  
2481          if ( $back) {
2482              $r .= "\t" . '<label id="label-' . esc_attr( $back ) . '" for="' . esc_attr( $back ) . '" class="back">' . "\n";
2483              $this->tabindex++;
2484              $r .= "\t\t" . '<input type="submit" id="' . esc_attr( $back ) . '" name="' . esc_attr( $back ) . '" class="button" value="' . esc_attr( $data_back['value'] ) . '" tabindex="' . $this->tabindex . '" />' . "\n";
2485              $r .= "\t" . '</label>' . "\n";
2486          }
2487  
2488          $r .= "\t" . '<label id="label-' . esc_attr( $forward ) . '" for="' . esc_attr( $forward ) . '" class="forward">' . "\n";
2489          $this->tabindex++;
2490          $r .= "\t\t" . '<input type="submit" id="' . esc_attr( $forward ) . '" name="' . esc_attr( $forward ) . '" class="button" value="' . esc_attr( $data_forward['value'] ) . '" tabindex="' . $this->tabindex . '" />' . "\n";
2491          $r .= "\t" . '</label>' . "\n";
2492  
2493          $r .= '</fieldset>' . "\n";
2494  
2495          echo $r;
2496      }
2497  
2498      /**
2499       * Prints hidden input elements containing the data inputted in a given step.
2500       *
2501       * @param integer $step Optional. The number of the step whose hidden inputs should be printed.
2502       * @return void
2503       **/
2504  	function hidden_step_inputs( $step = false )
2505      {
2506          if ( !$step ) {
2507              $step = $this->step;
2508          } elseif ( $step !== $this->step ) {
2509              $this->inject_form_values_into_data( $step );
2510          }
2511  
2512          $data = $this->data[$step]['form'];
2513  
2514          $r = '<fieldset>' . "\n";
2515  
2516          foreach ( $data as $key => $value ) {
2517              if ( 'forward_' !== substr( $key, 0, 8 ) && 'back_' !== substr( $key, 0, 5 ) ) {
2518                  $r .= "\t" . '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value['value'] ) . '" />' . "\n";
2519              }
2520          }
2521  
2522          $r .= '</fieldset>' . "\n";
2523  
2524          echo $r;
2525      }
2526  
2527      /**
2528       * Rewrites the admin user input into a select element containing existing WordPress administrators.
2529       *
2530       * @return boolean True if the select element was created, otherwise false.
2531       **/
2532      function populate_keymaster_user_login_from_user_tables()
2533      {
2534          $data =& $this->data[3]['form']['keymaster_user_login'];
2535  
2536          // Get the existing WordPress admin users
2537  
2538          // Setup variables and constants if available
2539          global $bb;
2540          if ( !empty( $this->data[2]['form']['wp_table_prefix']['value'] ) ) {
2541              $bb->wp_table_prefix = $this->data[2]['form']['wp_table_prefix']['value'];
2542          }
2543          if ( !empty( $this->data[2]['form']['user_bbdb_name']['value'] ) ) {
2544              $bb->user_bbdb_name = $this->data[2]['form']['user_bbdb_name']['value'];
2545          }
2546          if ( !empty( $this->data[2]['form']['user_bbdb_user']['value'] ) ) {
2547              $bb->user_bbdb_user = $this->data[2]['form']['user_bbdb_user']['value'];
2548          }
2549          if ( !empty( $this->data[2]['form']['user_bbdb_password']['value'] ) ) {
2550              $bb->user_bbdb_password = $this->data[2]['form']['user_bbdb_password']['value'];
2551          }
2552          if ( !empty( $this->data[2]['form']['user_bbdb_host']['value'] ) ) {
2553              $bb->user_bbdb_host = $this->data[2]['form']['user_bbdb_host']['value'];
2554          }
2555          if ( !empty( $this->data[2]['form']['user_bbdb_charset']['value'] ) ) {
2556              $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['user_bbdb_charset']['value'] );
2557          }
2558          if ( !empty( $this->data[2]['form']['user_bbdb_collate']['value'] ) ) {
2559              $bb->user_bbdb_charset = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['user_bbdb_collate']['value'] );
2560          }
2561          if ( !empty( $this->data[2]['form']['custom_user_table']['value'] ) ) {
2562              $bb->custom_user_table = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['custom_user_table']['value'] );
2563          }
2564          if ( !empty( $this->data[2]['form']['custom_user_meta_table']['value'] ) ) {
2565              $bb->custom_user_meta_table = preg_replace( '/[^a-z0-9_-]/i', '', $this->data[2]['form']['custom_user_meta_table']['value'] );
2566          }
2567  
2568          global $bbdb;
2569          global $bb_table_prefix;
2570  
2571          // Resolve the custom user tables for bpdb
2572          bb_set_custom_user_tables();
2573  
2574          if ( isset( $bb->custom_databases ) && isset( $bb->custom_databases['user'] ) ) {
2575              $bbdb->add_db_server( 'user', $bb->custom_databases['user'] );
2576          }
2577  
2578          // Add custom tables if required
2579          if ( isset( $bb->custom_tables['users'] ) || isset( $bb->custom_tables['usermeta'] ) ) {
2580              $bbdb->tables = array_merge( $bbdb->tables, $bb->custom_tables );
2581              if ( is_wp_error( $bbdb->set_prefix( $bb_table_prefix ) ) ) {
2582                  die( __( 'Your user table prefix may only contain letters, numbers and underscores.' ) );
2583              }
2584          }
2585  
2586          $bb_keymaster_meta_key       = $bbdb->escape( $bb_table_prefix . 'capabilities' );
2587          $wp_administrator_meta_key   = $bbdb->escape( $bb->wp_table_prefix . 'capabilities' );
2588          if ( !empty( $this->data[2]['form']['wordpress_mu_primary_blog_id']['value'] ) ) {
2589              $wp_administrator_meta_key = $bb->wp_table_prefix . $this->data[2]['form']['wordpress_mu_primary_blog_id']['value'] . '_capabilities';
2590          }
2591  
2592          $keymaster_query = <<<EOQ
2593              SELECT
2594                  user_login, user_email, display_name
2595              FROM
2596                  $bbdb->users
2597              LEFT JOIN
2598                  $bbdb->usermeta ON
2599                  $bbdb->users.ID = $bbdb->usermeta.user_id
2600              WHERE
2601                  (
2602                      (
2603                          meta_key = '$wp_administrator_meta_key' AND
2604                          meta_value LIKE '%administrator%'
2605                      ) OR
2606                      (
2607                          meta_key = '$bb_keymaster_meta_key' AND
2608                          meta_value LIKE '%keymaster%'
2609                      )
2610                  ) AND
2611                  user_email IS NOT NULL AND
2612                  user_email != ''
2613              ORDER BY
2614                  user_login;
2615  EOQ;
2616          $bbdb->suppress_errors();
2617  
2618          if ( $keymasters = $bbdb->get_results( $keymaster_query, ARRAY_A ) ) {
2619  
2620              $bbdb->suppress_errors( false );
2621  
2622              if ( count( $keymasters ) ) {
2623                  $email_maps = '';
2624                  $data['options']  = array();
2625                  $data['onchange'] = 'changeKeymasterEmail( this, \'keymaster_user_email\' );';
2626                  $data['note']     = __( 'Please select an existing bbPress Keymaster or WordPress administrator.' );
2627  
2628                  $data['options'][''] = '';
2629                  foreach ( $keymasters as $keymaster ) {
2630                      $email_maps .= 'emailMap[\'' . $keymaster['user_login'] . '\'] = \'' . $keymaster['user_email'] . '\';' . "\n\t\t\t\t\t\t\t\t";
2631                      if ( $keymaster['display_name'] ) {
2632                          $data['options'][$keymaster['user_login']] = $keymaster['user_login'] . ' (' . $keymaster['display_name'] . ')';
2633                      } else {
2634                          $data['options'][$keymaster['user_login']] = $keymaster['user_login'];
2635                      }
2636                  }
2637  
2638                  $this->strings[3]['scripts']['changeKeymasterEmail'] = <<<EOS
2639                          <script type="text/javascript" charset="utf-8">
2640  							function changeKeymasterEmail( selectObj, target ) {
2641                                  var emailMap = new Array;
2642                                  emailMap[''] = '';
2643                                  $email_maps
2644                                  var targetObj = document.getElementById( target );
2645                                  var selectedAdmin = selectObj.options[selectObj.selectedIndex].value;
2646                                  targetObj.value = emailMap[selectedAdmin];
2647                              }
2648                          </script>
2649  EOS;
2650  
2651                  $this->data[3]['form']['keymaster_user_type']['value'] = 'old';
2652  
2653                  return true;
2654              }
2655          }
2656  
2657          $bbdb->suppress_errors( false );
2658  
2659          return false;
2660      }
2661  
2662      /**
2663       * Sends HTTP headers and prints the page header.
2664       *
2665       * @return void
2666       **/
2667  	function header()
2668      {
2669          nocache_headers();
2670  
2671          bb_install_header( $this->strings[$this->step]['title'], $this->strings[$this->step]['h1'], true );
2672      }
2673  
2674      /**
2675       * Prints the page footer.
2676       *
2677       * @return void
2678       **/
2679  	function footer()
2680      {
2681          bb_install_footer();
2682      }
2683  
2684      /**
2685       * Prints the returned messages for the current step.
2686       *
2687       * @return void
2688       **/
2689  	function messages()
2690      {
2691          if ( isset( $this->strings[$this->step]['messages'] ) ) {
2692              $messages = $this->strings[$this->step]['messages'];
2693  
2694              // This count works as long as $messages is only two-dimensional
2695              $count = ( count( $messages, COUNT_RECURSIVE ) - count( $messages ) );
2696              $i = 0;
2697              $r = '';
2698              foreach ( $messages as $type => $paragraphs ) {
2699                  $class = $type ? $type : '';
2700  
2701                  foreach ( $paragraphs as $paragraph ) {
2702                      $i++;
2703                      $class = ( $i === $count ) ? ( $class . ' last' ) : $class;
2704                      $r .= '<p class="' . esc_attr( $class ) . '">' . $paragraph . '</p>' . "\n";
2705                  }
2706              }
2707              echo $r;
2708          }
2709      }
2710  
2711      /**
2712       * Prints the introduction paragraphs for the current step.
2713       *
2714       * @return void
2715       **/
2716  	function intro()
2717      {
2718          if ( 'incomplete' == $this->step_status[$this->step] && isset( $this->strings[$this->step]['intro'] ) ) {
2719              $messages = $this->strings[$this->step]['intro'];
2720              $count = count( $messages );
2721              $i = 0;
2722              $r = '';
2723              foreach ( $messages as $paragraph ) {
2724                  $i++;
2725                  $class = ( $i === $count ) ? 'intro last' : 'intro';
2726                  $r .= '<p class="' . $class . '">' . $paragraph . '</p>' . "\n";
2727              }
2728              echo $r;
2729          }
2730      }
2731  
2732      /**
2733       * Prints the standard header for each step.
2734       *
2735       * @param integer $step The number of the step whose header should be printed.
2736       * @return void
2737       **/
2738  	function step_header( $step )
2739      {
2740          $class = ( $step == $this->step ) ? 'open' : 'closed';
2741  
2742          $r = '<div id="' . esc_attr( 'step' . $step ) . '" class="' . $class . '">' . "\n";
2743          $r .= '<h2 class="' . $class . '">' . $this->strings[$step]['h2'] . '</h2>' . "\n";
2744          $r .= '<div>' . "\n";
2745  
2746          if ( $step < $this->step && $this->strings[$step]['status'] ) {
2747              $r .= '<p class="status">' . $this->strings[$step]['status'] . '</p>' . "\n";
2748          }
2749  
2750          echo $r;
2751  
2752          if ( $step == $this->step ) {
2753              $this->intro();
2754          }
2755  
2756          $this->tabindex = 0;
2757      }
2758  
2759      /**
2760       * Prints the standard step footer.
2761       *
2762       * @return void
2763       **/
2764  	function step_footer()
2765      {
2766          $r = '</div></div>' . "\n";
2767  
2768          echo $r;
2769      }
2770  } // END class BB_Install


Generated: Thu Dec 7 01:01:35 2017 Cross-referenced by PHPXref 0.7.1