[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
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 › Error' ), 198 'h1' => __( 'Oh dear!' ), 199 'messages' => array() 200 ), 201 0 => array( 202 'title' => sprintf( __( '%1$s › %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 › %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 › %2$s' ), __( 'bbPress installer' ), __( 'Step 2' ) ), 223 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 2' ), __( 'WordPress integration (optional)' ) ), 224 'status' => __( '« 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 › %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 › %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'] = __( '« 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' => __( '« 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' => __( '« 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' => __( '« 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'] = __( '« 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'] = __( '« 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'] = __( '« 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'][] = __( '• 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'][] = __( '• 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( __( '• This value is required to continue.' ) ); 1466 break(2); 1467 case 'urlparse': 1468 $errors[] = __( '• This does not appear to be a valid URL.' ); 1469 break; 1470 case 'urlscheme': 1471 $errors[] = __( '• The URL must begin with "http" or "https".' ); 1472 break; 1473 case 'urlhost': 1474 $errors[] = __( '• 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'][] = __( '• 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( __( '• This value is required to continue.' ) ); 1675 break(2); 1676 case 'urlparse': 1677 $errors[] = __( '• This does not appear to be a valid URL.' ); 1678 break; 1679 case 'urlscheme': 1680 $errors[] = __( '• The URL must begin with "http" or "https".' ); 1681 break; 1682 case 'urlhost': 1683 $errors[] = __( '• The URL does not contain a host name.' ); 1684 break; 1685 case 'userlogin': 1686 $errors[] = __( '• Contains disallowed characters which have been removed.' ); 1687 break; 1688 case 'email': 1689 $errors[] = __( '• 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…' ); 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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Dec 7 01:01:35 2017 | Cross-referenced by PHPXref 0.7.1 |