PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/forum/bb-admin/includes/class.bb-install.php

http://cartonbank.googlecode.com/
PHP | 1815 lines | 1255 code | 201 blank | 359 comment | 178 complexity | d573cea291e48bd1c9408271b9061e3f MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, LGPL-2.1, AGPL-1.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  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. * Whether or not we need to load some of the includes normally loaded by bb-settings.php
  17. *
  18. * @var boolean
  19. */
  20. var $load_includes = false;
  21. /**
  22. * An array of available languages to use in the installer
  23. *
  24. * @var array
  25. */
  26. var $languages = array( 'en_US' => 'en_US' );
  27. /**
  28. * The currently selected language for the installer
  29. *
  30. * @var string
  31. */
  32. var $language = 'en_US';
  33. /**
  34. * The current step in the install process
  35. *
  36. * @var integer
  37. */
  38. var $step;
  39. /**
  40. * Info about config files and their locations
  41. *
  42. * @var array
  43. */
  44. var $configs = array(
  45. 'writable' => false,
  46. 'bb-config.php' => false,
  47. 'config.php' => false
  48. );
  49. /**
  50. * An array of the current status of each step
  51. *
  52. * @var array
  53. */
  54. var $step_status = array(
  55. 0 => 'incomplete',
  56. 1 => 'incomplete',
  57. 2 => 'incomplete',
  58. 3 => 'incomplete',
  59. 4 => 'incomplete'
  60. );
  61. /**
  62. * An array of most strings in use, including errors
  63. *
  64. * @var array
  65. */
  66. var $strings = array();
  67. /**
  68. * The data being manipulated as we go through the forms
  69. *
  70. * @var array
  71. */
  72. var $data = array();
  73. /**
  74. * A boolean that can get flagged to stop posting of a form getting processed
  75. *
  76. * @var boolean
  77. */
  78. var $stop_process = false;
  79. /**
  80. * Keeps track of where the tabindex is up to
  81. *
  82. * @var integer
  83. */
  84. var $tabindex = 0;
  85. /**
  86. * Constructor
  87. *
  88. * Loads everything we might need to do the business
  89. *
  90. * @param string $caller The full path of the file that instantiated the class
  91. * @return boolean Always returns true
  92. */
  93. function BB_Install( $caller )
  94. {
  95. $this->caller = $caller;
  96. $this->set_initial_step();
  97. $this->define_paths();
  98. // We need to load these when bb-settings.php isn't loaded
  99. if ( $this->load_includes ) {
  100. require_once( BACKPRESS_PATH . 'functions.core.php' );
  101. require_once( BACKPRESS_PATH . 'functions.compat.php' );
  102. require_once( BACKPRESS_PATH . 'functions.formatting.php' );
  103. require_once( BACKPRESS_PATH . 'functions.plugin-api.php' );
  104. require_once( BACKPRESS_PATH . 'class.wp-error.php' );
  105. require_once( BB_PATH . BB_INC . 'functions.bb-core.php' );
  106. require_once( BB_PATH . BB_INC . 'functions.bb-meta.php' );
  107. require_once( BB_PATH . BB_INC . 'class.bp-options.php' );
  108. require_once( BACKPRESS_PATH . 'functions.bp-options.php' );
  109. require_once( BACKPRESS_PATH . 'functions.kses.php' );
  110. require_once( BB_PATH . BB_INC . 'functions.bb-l10n.php' );
  111. require_once( BB_PATH . BB_INC . 'functions.bb-template.php' );
  112. }
  113. $this->get_languages();
  114. $this->set_language();
  115. if ( $this->language ) {
  116. global $locale;
  117. global $l10n;
  118. $locale = $this->language;
  119. unset( $l10n['default'] );
  120. if ( !class_exists( 'MO' ) ) {
  121. require_once( BACKPRESS_PATH . 'pomo/mo.php' );
  122. }
  123. }
  124. // Load the default text localization domain. Doing this twice doesn't hurt too much.
  125. bb_load_default_textdomain();
  126. // Pull in locale data after loading text domain.
  127. if ( $this->load_includes ) {
  128. require_once( BB_PATH . BB_INC . 'class.bb-locale.php' );
  129. }
  130. global $bb_locale;
  131. $bb_locale = new BB_Locale();
  132. $this->prepare_strings();
  133. $this->check_prerequisites();
  134. $this->check_configs();
  135. if ( $this->step > -1 ) {
  136. $this->set_step();
  137. $this->prepare_data();
  138. $this->process_form();
  139. }
  140. return true;
  141. }
  142. /**
  143. * Set initial step
  144. *
  145. * Sets the step from the post data and keeps it within range
  146. *
  147. * @return integer The calculated step
  148. */
  149. function set_initial_step()
  150. {
  151. // Set the step based on the $_POST value or 0
  152. $this->step = $_POST['step'] ? (integer) $_POST['step'] : 0;
  153. // Make sure the requested step is from 0-4
  154. if ( 0 > $this->step || 4 < $this->step ) {
  155. $this->step = 0;
  156. }
  157. return $this->step;
  158. }
  159. /**
  160. * Prepare text strings
  161. *
  162. * Sets up many of the strings to be used by the class that may
  163. * be later subject to change due to processing of the forms
  164. */
  165. function prepare_strings()
  166. {
  167. $this->strings = array(
  168. -1 => array(
  169. 'title' => __( 'bbPress &rsaquo; Error' ),
  170. 'h1' => __( 'Oh dear!' ),
  171. 'messages' => array()
  172. ),
  173. 0 => array(
  174. 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Welcome' ) ),
  175. 'h2' => __( 'Welcome to the bbPress installer' ),
  176. 'status' => '',
  177. 'messages' => array(),
  178. 'intro' => array(
  179. __( 'We\'re now going to go through a few steps to get you up and running.' ),
  180. __( 'Ready? Then let\'s get started!' )
  181. )
  182. ),
  183. 1 => array(
  184. 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 1' ) ),
  185. 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 1' ), __( 'Database configuration' ) ),
  186. 'status' => '',
  187. 'intro' => array(
  188. __( '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.' ),
  189. __( 'If you\'re not sure what to put here, contact your web hosting provider.' )
  190. ),
  191. 'messages' => array()
  192. ),
  193. 2 => array(
  194. 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 2' ) ),
  195. 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 2' ), __( 'WordPress integration (optional)' ) ),
  196. 'status' => __( '&laquo; skipped' ),
  197. 'intro' => array(
  198. __( '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.' )
  199. ),
  200. 'messages' => array(),
  201. 'form_errors' => array()
  202. ),
  203. 3 => array(
  204. 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Step 3' ) ),
  205. 'h2' => sprintf( __( '%1$s - %2$s' ), __( 'Step 3' ), __( 'Site settings' ) ),
  206. 'status' => '',
  207. 'intro' => array(
  208. __( 'Finalize your installation by adding a name, your first user and your first forum.' )
  209. ),
  210. 'messages' => array(),
  211. 'form_errors' => array(),
  212. 'scripts' => array()
  213. ),
  214. 4 => array(
  215. 'title' => sprintf( __( '%1$s &rsaquo; %2$s' ), __( 'bbPress installer' ), __( 'Finished' ) ),
  216. 'h2' => __( 'Installation complete!' ),
  217. 'messages' => array()
  218. )
  219. );
  220. }
  221. /**
  222. * Check installation pre-requisites
  223. *
  224. * Checks for appropriate PHP extensions.
  225. *
  226. * @return boolean False if any pre-requisites are not met, otherwise true
  227. */
  228. function check_prerequisites()
  229. {
  230. // BPDB wants the MySQL extension - this is also checked when BPDB is initialised so may be a bit redundant here
  231. if ( !extension_loaded( 'mysql' ) ) {
  232. $this->strings[-1]['messages']['error'][] = __( 'Your PHP installation appears to be missing the MySQL extension which is required for bbPress' );
  233. $this->step = -1;
  234. }
  235. if ( defined( 'BB_IS_WP_LOADED' ) && BB_IS_WP_LOADED ) {
  236. $this->strings[-1]['messages']['error'][] = __( 'Please complete your installation before attempting to include WordPress within bbPress' );
  237. $this->step = -1;
  238. }
  239. if ( $this->step === -1 ) {
  240. return false;
  241. }
  242. return true;
  243. }
  244. /**
  245. * Define path constants
  246. *
  247. * Sets some bbPress constants if they are not otherwise available based
  248. * on the classes initiating file path.
  249. *
  250. * @return boolean False if no path was supplied, otherwise always true
  251. */
  252. function define_paths()
  253. {
  254. if ( !$this->caller ) {
  255. return false;
  256. }
  257. if ( !defined( 'BACKPRESS_PATH' ) ) {
  258. // Define BACKPRESS_PATH
  259. // Tell us to load includes because bb-settings.php was not loaded
  260. // bb-settings.php is generally not loaded on steps -1, 0 and 1 but
  261. // there are exceptions, so this is safer than just reading the step
  262. $this->load_includes = true;
  263. define( 'BACKPRESS_PATH', BB_PATH . BB_INC . 'backpress/' );
  264. }
  265. // Define the language file directory
  266. if ( !defined( 'BB_LANG_DIR' ) ) {
  267. define( 'BB_LANG_DIR', BB_PATH . 'my-languages/' );
  268. }
  269. return true;
  270. }
  271. /**
  272. * Gets an array of available languages form the language directory
  273. *
  274. * @return array
  275. */
  276. function get_languages()
  277. {
  278. foreach ( bb_glob( BB_LANG_DIR . '*.mo' ) as $language ) {
  279. if ( substr( $language, 0, 18 ) === 'continents-cities-' ) {
  280. continue;
  281. }
  282. $language = str_replace( '.mo', '', basename( $language ) );
  283. $this->languages[$language] = $language;
  284. }
  285. return $this->languages;
  286. }
  287. /**
  288. * Returns a language selector for switching installation languages
  289. *
  290. * @return string|false Either the html for the selector or false if there are no languages
  291. */
  292. function get_language_selector()
  293. {
  294. // Don't provide a selection if there is only english
  295. if ( 2 > count( $this->languages ) ) {
  296. return false;
  297. }
  298. $r = '<script type="text/javascript" charset="utf-8">' . "\n";
  299. $r .= "\t" . 'function changeLanguage(selectObj) {' . "\n";
  300. $r .= "\t\t" . 'var selectedLanguage = selectObj.options[selectObj.selectedIndex].value;' . "\n";
  301. $r .= "\t\t" . 'location.href = "install.php?language=" + selectedLanguage;' . "\n";
  302. $r .= "\t" . '}' . "\n";
  303. $r .= '</script>' . "\n";
  304. //$r .= '<form id="lang" action="install.php">' . "\n";
  305. $r .= "\t" . '<fieldset>' . "\n";
  306. $r .= "\t\t" . '<label class="has-note has-label for-select">' . "\n";
  307. $r .= "\t\t\t" . '<span>' . __( 'Installation language' ) . '</span>' . "\n";
  308. $this->tabindex++;
  309. $r .= "\t\t\t" . '<select class="has-note" onchange="changeLanguage(this);" name="language" tabindex="' . $this->tabindex . '">' . "\n";
  310. foreach ( $this->languages as $language ) {
  311. $selected = '';
  312. if ( $language == $this->language ) {
  313. $selected = ' selected="selected"';
  314. }
  315. $r .= "\t\t\t\t" . '<option value="' . $language . '"' . $selected . '>' . $language . '</option>' . "\n";
  316. }
  317. $r .= "\t\t\t" . '</select>' . "\n";
  318. $r .= "\t\t\t" . '<a class="note-toggle" href="javascript:void(0);" onclick="toggleNote(\'note-language\');">?</a>' . "\n";
  319. $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";
  320. $r .= "\t\t\t" . '<div class="clear"></div>' . "\n";
  321. $r .= "\t\t" . '</label>' . "\n";
  322. $r .= "\t" . '</fieldset>' . "\n";
  323. //$r .= '</form>' . "\n";
  324. echo $r;
  325. }
  326. /**
  327. * Sets the current installation language
  328. *
  329. * @return string The currently set language
  330. */
  331. function set_language()
  332. {
  333. if ( isset( $_COOKIE['bb_install_language'] ) && 1 < count( $this->languages ) ) {
  334. if ( in_array( $_COOKIE['bb_install_language'], $this->languages ) ) {
  335. $this->language = $_COOKIE['bb_install_language'];
  336. }
  337. }
  338. $language_requested = false;
  339. if ( isset( $_POST['language'] ) && $_POST['language'] ) {
  340. $language_requested = (string) $_POST['language'];
  341. } elseif ( isset( $_GET['language'] ) && $_GET['language'] ) {
  342. $language_requested = (string) $_GET['language'];
  343. }
  344. if ( $language_requested && 1 < count( $this->languages ) ) {
  345. if ( in_array( $language_requested, $this->languages ) ) {
  346. $this->language = $language_requested;
  347. setcookie( 'bb_install_language', $this->language );
  348. }
  349. }
  350. if ( !$this->language || 'en_US' === $this->language ) {
  351. $this->language = 'en_US';
  352. setcookie( 'bb_install_language', ' ', time() - 31536000 );
  353. }
  354. return $this->language;
  355. }
  356. /**
  357. * Tests whether database tables exist
  358. *
  359. * Checks for the existence of the forum table in the database that is
  360. * currently configured.
  361. *
  362. * @return boolean False if the table isn't found, otherwise true
  363. */
  364. function database_tables_are_installed()
  365. {
  366. global $bbdb;
  367. $bbdb->suppress_errors();
  368. $installed = (boolean) $bbdb->get_results( 'DESCRIBE `' . $bbdb->forums . '`;', ARRAY_A );
  369. $bbdb->suppress_errors( false );
  370. return $installed;
  371. }
  372. /**
  373. * Tests whether an option is set in the database
  374. *
  375. * @return boolean False if the option isn't set, otherwise true
  376. */
  377. function bb_options_are_set()
  378. {
  379. if ( $this->load_includes ) {
  380. return false;
  381. }
  382. if ( !bb_get_option( 'uri' ) ) {
  383. return false;
  384. }
  385. return true;
  386. }
  387. /**
  388. * Tests whether bbPress is installed
  389. *
  390. * @return boolean False if bbPress isn't installed, otherwise true
  391. */
  392. function is_installed()
  393. {
  394. if ( !$this->database_tables_are_installed() ) {
  395. return false;
  396. }
  397. if ( !$this->bb_options_are_set() ) {
  398. return false;
  399. }
  400. return true;
  401. }
  402. /**
  403. * Checks for configs and sets variables describing current install state
  404. *
  405. * @return integer The current step we should be on based on the existence of the config file
  406. */
  407. function check_configs()
  408. {
  409. // Check for a config file
  410. if ( file_exists( BB_PATH . 'bb-config.php' ) ) {
  411. $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
  412. } elseif ( file_exists( dirname( BB_PATH ) . '/bb-config.php' ) ) {
  413. $this->configs['bb-config.php'] = dirname( BB_PATH ) . '/bb-config.php';
  414. }
  415. // Check for an old config file
  416. if ( file_exists( BB_PATH . 'config.php' ) ) {
  417. $this->configs['config.php'] = BB_PATH . 'config.php';
  418. } elseif ( file_exists( dirname( BB_PATH ) . '/config.php' ) ) {
  419. $this->configs['config.php'] = dirname( BB_PATH ) . '/config.php';
  420. }
  421. if ( $this->configs['config.php'] && !$this->configs['bb-config.php'] ) {
  422. // There is an old school config file
  423. // Step -1 is where we send fatal errors from any screen
  424. $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.' );
  425. $this->step = -1;
  426. return $this->step;
  427. }
  428. // Check if bbPress is already installed
  429. // Is there a current config file
  430. if ( $this->configs['bb-config.php'] ) {
  431. // Is it valid
  432. if ( $this->validate_current_config() ) {
  433. // Step 1 is complete
  434. $this->step_status[1] = 'complete';
  435. $this->strings[1]['status'] = __( '&laquo; completed' );
  436. // On step 1 we want to report that the file is good and allow the user to continue
  437. if ( $this->step === 1 ) {
  438. // Stop form processing if it is posted
  439. $this->stop_process = true;
  440. // Display a nice message saying the config file exists
  441. $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.' );
  442. return $this->step;
  443. }
  444. } else {
  445. // Invalid config files on any step cause us to exit to step 0
  446. $this->strings[-1]['messages']['error'][] = __( 'An invalid configuration file was found at <code>bb-config.php</code><br />The installation cannot continue.' );
  447. $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.' );
  448. $this->step = -1;
  449. }
  450. // If we have made it this far, then we can check if the database tables exist and have content
  451. if ( $this->is_installed() ) {
  452. // The database is installed
  453. // The following standard functions should be available
  454. if ( bb_get_option( 'bb_db_version' ) > bb_get_option_from_db( 'bb_db_version' ) ) {
  455. // The database needs upgrading
  456. $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed, but appears to require an upgrade.' );
  457. } else {
  458. $this->strings[-1]['messages'][0][] = __( 'bbPress is already installed.' );
  459. }
  460. $this->strings[-1]['messages'][0][] = sprintf(
  461. __( 'Perhaps you meant to run the <a href="%s">upgrade script</a> instead?' ),
  462. bb_get_uri( 'bb-admin/upgrade.php', null, BB_URI_CONTEXT_A_HREF + BB_URI_CONTEXT_BB_ADMIN )
  463. );
  464. $this->step = -1;
  465. }
  466. } else {
  467. if ( 2 > $this->step && !file_exists( BB_PATH . 'bb-config-sample.php' ) ) {
  468. // There is no sample config file
  469. $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.' );
  470. $this->step = 0;
  471. }
  472. if ( 1 !== $this->step ) {
  473. // There is no config file, go back to the beginning
  474. $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.' );
  475. $this->step = 0;
  476. }
  477. }
  478. // Check if the config file path is writable
  479. if ( file_exists( $this->configs['bb-config.php'] ) ) {
  480. if ( is_writable( $this->configs['bb-config.php'] ) ) {
  481. $this->configs['writable'] = true;
  482. }
  483. } elseif ( is_writable( BB_PATH ) ) {
  484. $this->configs['writable'] = true;
  485. }
  486. return $this->step;
  487. }
  488. /**
  489. * Determines if the current config is valid
  490. *
  491. * @return boolean False if the config is bad, otherwise true
  492. */
  493. function validate_current_config()
  494. {
  495. // If we are validating then the config file has already been included
  496. // So we can just check for valid constants
  497. // The required constants for a valid config file
  498. $required_constants = array(
  499. 'BBDB_NAME',
  500. 'BBDB_USER',
  501. 'BBDB_PASSWORD',
  502. 'BBDB_HOST'
  503. );
  504. // Check the required constants are defined
  505. foreach ( $required_constants as $required_constant ) {
  506. if ( !defined( $required_constant ) ) {
  507. return false;
  508. }
  509. }
  510. global $bb_table_prefix;
  511. if ( !isset( $bb_table_prefix ) ) {
  512. return false;
  513. }
  514. // Everthing is OK so far, validate the connection as well
  515. return $this->validate_current_database();
  516. }
  517. /**
  518. * Validates the current database settings
  519. *
  520. * @return boolean False if the current database isn't valid, otherwise true
  521. */
  522. function validate_current_database()
  523. {
  524. global $bbdb;
  525. $db = $bbdb->db_connect( "SELECT * FROM $bbdb->forums LIMIT 1" );
  526. if ( !is_resource( $db ) ) {
  527. return false;
  528. }
  529. return true;
  530. }
  531. /**
  532. * Sets up default values for input data as well as labels and notes
  533. *
  534. * @return void
  535. */
  536. function prepare_data()
  537. {
  538. /**
  539. * Should be exactly the same as the default value of the KEYS in bb-config-sample.php
  540. * @since 1.0
  541. */
  542. $_bb_default_secret_key = 'put your unique phrase here';
  543. $this->data = array(
  544. 0 => array(
  545. 'form' => array(
  546. 'forward_0_0' => array(
  547. 'value' => __( 'Go to step 1' )
  548. )
  549. )
  550. ),
  551. 1 => array(
  552. 'form' => array(
  553. 'bbdb_name' => array(
  554. 'value' => '',
  555. 'label' => __( 'Database name' ),
  556. 'note' => __( 'The name of the database in which you want to run bbPress.' )
  557. ),
  558. 'bbdb_user' => array(
  559. 'value' => '',
  560. 'label' => __( 'Database user' ),
  561. 'note' => __( 'The database user that has access to that database.' ),
  562. 'autocomplete' => 'off'
  563. ),
  564. 'bbdb_password' => array(
  565. 'type' => 'password',
  566. 'value' => '',
  567. 'label' => __( 'Database password' ),
  568. 'note' => __( 'That database user\'s password.' ),
  569. 'autocomplete' => 'off'
  570. ),
  571. 'bb_lang' => array(
  572. 'value' => '',
  573. 'label' => __( 'Language' ),
  574. '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 )
  575. ),
  576. 'toggle_1' => array(
  577. 'value' => 0,
  578. 'label' => __( 'Show advanced settings' ),
  579. 'note' => __( 'These settings usually do not have to be changed.' ),
  580. 'checked' => '',
  581. 'display' => 'none'
  582. ),
  583. 'bbdb_host' => array(
  584. 'value' => 'localhost',
  585. 'label' => __( 'Database host' ),
  586. '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>.' ),
  587. 'prerequisite' => 'toggle_1'
  588. ),
  589. 'bbdb_charset' => array(
  590. 'value' => 'utf8',
  591. 'label' => __( 'Database character set' ),
  592. 'note' => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
  593. 'prerequisite' => 'toggle_1'
  594. ),
  595. 'bbdb_collate' => array(
  596. 'value' => '',
  597. 'label' => __( 'Database character collation' ),
  598. 'note' => __( 'The character collation value set when the database was created.' ),
  599. 'prerequisite' => 'toggle_1'
  600. ),
  601. /*
  602. 'bb_auth_key' => array(
  603. 'value' => $_bb_default_secret_key,
  604. 'label' => __( 'bbPress "auth" cookie key' ),
  605. '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.' ),
  606. 'prerequisite' => 'toggle_1'
  607. ),
  608. 'bb_secure_auth_key' => array(
  609. 'value' => $_bb_default_secret_key,
  610. 'label' => __( 'bbPress "secure auth" cookie key' ),
  611. '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.' ),
  612. 'prerequisite' => 'toggle_1'
  613. ),
  614. 'bb_logged_in_key' => array(
  615. 'value' => $_bb_default_secret_key,
  616. 'label' => __( 'bbPress "logged in" cookie key' ),
  617. '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.' ),
  618. 'prerequisite' => 'toggle_1'
  619. ),
  620. 'bb_nonce_key' => array(
  621. 'value' => $_bb_default_secret_key,
  622. 'label' => __( 'bbPress "nonce" key' ),
  623. 'note' => __( 'This should be a unique and secret phrase, it will be used to make form submission harder for an attacker to spoof.' ),
  624. 'prerequisite' => 'toggle_1'
  625. ),
  626. */
  627. 'bb_table_prefix' => array(
  628. 'value' => 'bb_',
  629. 'label' => __( 'Table name prefix' ),
  630. 'note' => __( 'If you are running multiple bbPress sites in a single database, you will probably want to change this.' ),
  631. 'prerequisite' => 'toggle_1'
  632. ),
  633. 'config' => array(
  634. 'value' => '',
  635. 'label' => __( 'Contents for <code>bb-config.php</code>' ),
  636. 'note' => __( 'Once you have created the configuration file, you can check for it below.' )
  637. ),
  638. 'forward_1_0' => array(
  639. 'value' => __( 'Save database configuration file' )
  640. ),
  641. 'back_1_1' => array(
  642. 'value' => __( '&laquo; Go back' )
  643. ),
  644. 'forward_1_1' => array(
  645. 'value' => __( 'Check for configuration file' )
  646. ),
  647. 'forward_1_2' => array(
  648. 'value' => __( 'Go to step 2' )
  649. )
  650. )
  651. ),
  652. 2 => array(
  653. 'form' => array(
  654. 'toggle_2_0' => array(
  655. 'value' => 0,
  656. 'label' => __( 'Add integration settings' ),
  657. 'note' => __( 'If you want to integrate bbPress with an existing WordPress site.' ),
  658. 'checked' => '',
  659. 'display' => 'none',
  660. 'toggle_value' => array(
  661. 'target' => 'forward_2_0',
  662. 'off_value' => __( 'Skip WordPress integration' ),
  663. 'on_value' => __( 'Save WordPress integration settings' )
  664. )
  665. ),
  666. 'toggle_2_1' => array(
  667. 'value' => 0,
  668. 'label' => __( 'Add cookie integration settings' ),
  669. 'note' => __( 'If you want to allow shared logins with an existing WordPress site.' ),
  670. 'checked' => '',
  671. 'display' => 'none',
  672. 'prerequisite' => 'toggle_2_0'
  673. ),
  674. 'wp_siteurl' => array(
  675. 'value' => '',
  676. 'label' => __( 'WordPress address (URL)' ),
  677. 'note' => __( 'This value should exactly match the <strong>WordPress address (URL)</strong> setting in your WordPress general settings.' ),
  678. 'prerequisite' => 'toggle_2_1'
  679. ),
  680. 'wp_home' => array(
  681. 'value' => '',
  682. 'label' => __( 'Blog address (URL)' ),
  683. 'note' => __( 'This value should exactly match the <strong>Blog address (URL)</strong> setting in your WordPress general settings.' ),
  684. 'prerequisite' => 'toggle_2_1'
  685. ),
  686. 'wp_auth_key' => array(
  687. 'value' => '',
  688. 'label' => __( 'WordPress "auth" cookie key' ),
  689. '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.' ),
  690. 'prerequisite' => 'toggle_2_1',
  691. 'autocomplete' => 'off'
  692. ),
  693. 'wp_auth_salt' => array(
  694. 'value' => '',
  695. 'label' => __( 'WordPress "auth" cookie salt' ),
  696. '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.' ),
  697. 'prerequisite' => 'toggle_2_1',
  698. 'autocomplete' => 'off'
  699. ),
  700. 'wp_secure_auth_key' => array(
  701. 'value' => '',
  702. 'label' => __( 'WordPress "secure auth" cookie key' ),
  703. '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.' ),
  704. 'prerequisite' => 'toggle_2_1',
  705. 'autocomplete' => 'off'
  706. ),
  707. 'wp_secure_auth_salt' => array(
  708. 'value' => '',
  709. 'label' => __( 'WordPress "secure auth" cookie salt' ),
  710. '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.' ),
  711. 'prerequisite' => 'toggle_2_1',
  712. 'autocomplete' => 'off'
  713. ),
  714. 'wp_logged_in_key' => array(
  715. 'value' => '',
  716. 'label' => __( 'WordPress "logged in" cookie key' ),
  717. '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.' ),
  718. 'prerequisite' => 'toggle_2_1',
  719. 'autocomplete' => 'off'
  720. ),
  721. 'wp_logged_in_salt' => array(
  722. 'value' => '',
  723. 'label' => __( 'WordPress "logged in" cookie salt' ),
  724. '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.' ),
  725. 'prerequisite' => 'toggle_2_1',
  726. 'autocomplete' => 'off'
  727. ),
  728. 'toggle_2_2' => array(
  729. 'value' => 0,
  730. 'label' => __( 'Add user database integration settings' ),
  731. 'note' => __( 'If you want to share user data with an existing WordPress site.' ),
  732. 'checked' => '',
  733. 'display' => 'none',
  734. 'prerequisite' => 'toggle_2_0'
  735. ),
  736. 'wp_table_prefix' => array(
  737. 'value' => 'wp_',
  738. 'default_value' => '', // Used when setting is ignored
  739. 'label' => __( 'User database table prefix' ),
  740. '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>.' ),
  741. 'prerequisite' => 'toggle_2_2'
  742. ),
  743. 'wordpress_mu_primary_blog_id' => array(
  744. 'value' => '',
  745. 'default_value' => '',
  746. 'label' => __( 'WordPress MU primary blog ID' ),
  747. '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' ),
  748. 'prerequisite' => 'toggle_2_2'
  749. ),
  750. 'toggle_2_3' => array(
  751. 'value' => 0,
  752. 'label' => __( 'Show advanced database settings' ),
  753. 'note' => __( 'If your bbPress and WordPress site do not share the same database, then you will need to add advanced settings.' ),
  754. 'checked' => '',
  755. 'display' => 'none',
  756. 'prerequisite' => 'toggle_2_2'
  757. ),
  758. 'user_bbdb_name' => array(
  759. 'value' => '',
  760. 'label' => __( 'User database name' ),
  761. 'note' => __( 'The name of the database in which your user tables reside.' ),
  762. 'prerequisite' => 'toggle_2_3'
  763. ),
  764. 'user_bbdb_user' => array(
  765. 'value' => '',
  766. 'label' => __( 'User database user' ),
  767. 'note' => __( 'The database user that has access to that database.' ),
  768. 'prerequisite' => 'toggle_2_3',
  769. 'autocomplete' => 'off'
  770. ),
  771. 'user_bbdb_password' => array(
  772. 'type' => 'password',
  773. 'value' => '',
  774. 'label' => __( 'User database password' ),
  775. 'note' => __( 'That database user\'s password.' ),
  776. 'prerequisite' => 'toggle_2_3',
  777. 'autocomplete' => 'off'
  778. ),
  779. 'user_bbdb_host' => array(
  780. 'value' => '',
  781. 'label' => __( 'User database host' ),
  782. '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>.' ),
  783. 'prerequisite' => 'toggle_2_3'
  784. ),
  785. 'user_bbdb_charset' => array(
  786. 'value' => '',
  787. 'label' => __( 'User database character set' ),
  788. 'note' => __( 'The best choice is <strong>utf8</strong>, but you will need to match the character set which you created the database with.' ),
  789. 'prerequisite' => 'toggle_2_3'
  790. ),
  791. 'user_bbdb_collate' => array(
  792. 'value' => '',
  793. 'label' => __( 'User database character collation' ),
  794. 'note' => __( 'The character collation value set when the user database was created.' ),
  795. 'prerequisite' => 'toggle_2_3'
  796. ),
  797. 'custom_user_table' => array(
  798. 'value' => '',
  799. 'label' => __( 'User database "user" table' ),
  800. 'note' => __( 'The complete table name, including any prefix.' ),
  801. 'prerequisite' => 'toggle_2_3'
  802. ),
  803. 'custom_user_meta_table' => array(
  804. 'value' => '',
  805. 'label' => __( 'User database "user meta" table' ),
  806. 'note' => __( 'The complete table name, including any prefix.' ),
  807. 'prerequisite' => 'toggle_2_3'
  808. ),
  809. 'forward_2_0' => array(
  810. 'value' => __( 'Skip WordPress integration' )
  811. ),
  812. 'back_2_1' => array(
  813. 'value' => __( '&laquo; Go back' )
  814. ),
  815. 'forward_2_1' => array(
  816. 'value' => __( 'Go to step 3' )
  817. )
  818. )
  819. ),
  820. 3 => array(
  821. 'form' => array(
  822. 'name' => array(
  823. 'value' => '',
  824. 'label' => __( 'Site name' ),
  825. 'note' => __( 'This is what you are going to call your bbPress site.' )
  826. ),
  827. 'uri' => array(
  828. 'value' => $this->guess_uri(),
  829. 'label' => __( 'Site address (URL)' ),
  830. 'note' => __( 'We have attempted to guess this, it\'s usually correct, but change it here if you wish.' )
  831. ),
  832. 'keymaster_user_login' => array(
  833. 'value' => '',
  834. 'maxlength' => 60,
  835. 'label' => __( '"Key Master" Username' ),
  836. 'note' => __( 'This is the user login for the initial bbPress administrator (known as a "Key Master").' ),
  837. 'autocomplete' => 'off'
  838. ),
  839. 'keymaster_user_email' => array(
  840. 'value' => '',
  841. 'maxlength' => 100,
  842. 'label' => __( '"Key Master" Email address' ),
  843. 'note' => __( 'The login details will be emailed to this address.' ),
  844. 'autocomplete' => 'off'
  845. ),
  846. 'keymaster_user_type' => array(
  847. 'value' => 'new'
  848. ),
  849. 'forum_name' => array(
  850. 'value' => '',
  851. 'maxlength' => 150,
  852. 'label' => __( 'First forum name' ),
  853. 'note' => __( 'This can be changed after installation, so don\'t worry about it too much.' )
  854. ),
  855. 'forward_3_0' => array(
  856. 'value' => __( 'Save site settings' )
  857. ),
  858. 'back_3_1' => array(
  859. 'value' => __( '&laquo; Go back' )
  860. ),
  861. 'forward_3_1' => array(
  862. 'value' => __( 'Complete the installation' )
  863. )
  864. )
  865. ),
  866. 4 => array(
  867. 'form' => array(
  868. 'toggle_4' => array(
  869. 'value' => 0,
  870. 'label' => __( 'Show installation messages' )
  871. ),
  872. 'error_log' => array(
  873. 'value' => '',
  874. 'label' => __( 'Installation errors' )
  875. ),
  876. 'installation_log' => array(
  877. 'value' => '',
  878. 'label' => __( 'Installation log' )
  879. )
  880. )
  881. )
  882. );
  883. }
  884. /**
  885. * Guesses the final installed URI based on the location of the install script
  886. *
  887. * @return string The guessed URI
  888. */
  889. function guess_uri()
  890. {
  891. global $bb;
  892. if ( $bb->uri ) {
  893. $uri = $bb->uri;
  894. } else {
  895. $schema = 'http://';
  896. if ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' ) {
  897. $schema = 'https://';
  898. }
  899. $uri = preg_replace( '|/bb-admin/.*|i', '/', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
  900. }
  901. return rtrim( $uri, " \t\n\r\0\x0B/" ) . '/';
  902. }
  903. /**
  904. * Writes the given alterations to file
  905. *
  906. * @param $file_source string The full path to the file to be read from
  907. * @param $file_target string The full path to the file to be written to
  908. * @param $alterations array An array of arrays containing alterations to be made
  909. * @return void
  910. */
  911. function write_lines_to_file( $file_source, $file_target, $alterations )
  912. {
  913. if ( !$file_source || !file_exists( $file_source ) || !is_file( $file_source ) ) {
  914. return -1;
  915. }
  916. if ( !$file_target ) {
  917. $file_target = $file_source;
  918. }
  919. if ( !$alterations || !is_array( $alterations ) ) {
  920. return -2;
  921. }
  922. /*
  923. Alterations array takes the form
  924. array(
  925. '1st 20 chars of line' => array( 'Search string', 'Replacement string' ),
  926. '1st 20 chars of line' => array( 'Search string', 'Replacement string' )
  927. );
  928. */
  929. // Get the existing lines in the file
  930. $lines = file( $file_source );
  931. // Initialise an array to store the modified lines
  932. $modified_lines = array();
  933. // Loop through the lines and modify them
  934. foreach ( $lines as $line ) {
  935. if ( isset( $alterations[substr( $line, 0, 20 )] ) ) {
  936. $alteration = $alterations[substr( $line, 0, 20 )];
  937. $modified_lines[] = str_replace( $alteration[0], $alteration[1], $line );
  938. } else {
  939. $modified_lines[] = $line;
  940. }
  941. }
  942. $writable = true;
  943. if ( file_exists( $file_target ) ) {
  944. if ( !is_writable( $file_target ) ) {
  945. $writable = false;
  946. }
  947. } else {
  948. $dir_target = dirname( $file_target );
  949. if ( file_exists( $dir_target ) ) {
  950. if ( !is_writable( $dir_target ) || !is_dir( $dir_target ) ) {
  951. $writable = false;
  952. }
  953. } else {
  954. $writable = false;
  955. }
  956. }
  957. if ( !$writable ) {
  958. return trim( join( null, $modified_lines ) );
  959. }
  960. // Open the file for writing - rewrites the whole file
  961. $file_handle = fopen( $file_target, 'w' );
  962. // Write lines one by one to avoid OS specific newline hassles
  963. foreach ( $modified_lines as $modified_line ) {
  964. if ( false !== strpos( $modified_line, '?>' ) ) {
  965. $modified_line = '?>';
  966. }
  967. fwrite( $file_handle, $modified_line );
  968. if ( $modified_line == '?>' ) {
  969. break;
  970. }
  971. }
  972. // Close the config file
  973. fclose( $file_handle );
  974. @chmod( $file_target, 0666 );
  975. return 1;
  976. }
  977. /**
  978. * Reports whether the request method is post or not
  979. *
  980. * @return boolean True if the page was posted, otherwise false
  981. */
  982. function is_posted()
  983. {
  984. if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) ) {
  985. return true;
  986. }
  987. return false;
  988. }
  989. /**
  990. * Determines which step the installer is on based on user input
  991. *
  992. * @return boolean Always returns true
  993. **/
  994. function set_step()
  995. {
  996. if ( $this->is_posted() ) {
  997. switch ( $this->step ) {
  998. case 1:
  999. $this->set_language();
  1000. if ( $_POST['forward_0_0'] ) {
  1001. $this->stop_process = 1;
  1002. }
  1003. break;
  1004. case 2:
  1005. if ( $_POST['forward_1_2'] ) {
  1006. $this->stop_process = 1;
  1007. }
  1008. break;
  1009. case 3:
  1010. // If this is actually a request to go back to step 2
  1011. if ( $_POST['back_2_1'] ) {
  1012. $this->step = 2;
  1013. break;
  1014. }
  1015. // If we have come forward from step 2 then don't process form 3
  1016. if ( $_POST['forward_2_1'] ) {
  1017. $this->stop_process = true;
  1018. }
  1019. // Determine what the status of the previous step was based on input
  1020. if ( $_POST['toggle_2_0'] ) {
  1021. $this->strings[2]['status'] = __( '&laquo; completed' );
  1022. $this->step_status[2] = 'complete';
  1023. }
  1024. break;
  1025. case 4:
  1026. // Determine what the status of the previous step was based on input
  1027. if ( $_POST['toggle_2_0'] ) {
  1028. $this->strings[2]['status'] = __( '&laquo; completed' );
  1029. $this->step_status[2] = 'complete';
  1030. }
  1031. // If this is actually a request to go back to step 3
  1032. if ( $_POST['back_3_1'] ) {
  1033. $this->step = 3;
  1034. break;
  1035. }
  1036. // We have to have come forward from step 3
  1037. if ( $_POST['forward_3_1'] ) {
  1038. $this->strings[3]['status'] = __( '&laquo; completed' );
  1039. $this->step_status[3] = 'complete';
  1040. } else {
  1041. $this->step = 2;
  1042. }
  1043. break;
  1044. }
  1045. }
  1046. return true;
  1047. }
  1048. /**
  1049. * Sanitizes all data stored in the data array
  1050. *
  1051. * @return boolean Always returns true
  1052. **/
  1053. function sanitize_form_data()
  1054. {
  1055. foreach ( $this->data as $step => $data ) {
  1056. if ( isset( $data['form'] ) && is_array( $data['form'] ) ) {
  1057. foreach ( $data['form'] as $key => $value ) {
  1058. $this->data[$step]['form'][$key]['value'] = esc_attr( $value['value'] );
  1059. }
  1060. }
  1061. }
  1062. return true;
  1063. }
  1064. /**
  1065. * Directs processing of the form data based on the current step
  1066. *
  1067. * @return boolean Always returns true
  1068. **/
  1069. function process_form()
  1070. {
  1071. if ( $this->is_posted() && !$this->stop_process ) {
  1072. switch ( $this->step ) {
  1073. case 1:
  1074. $this->process_form_config_file();
  1075. break;
  1076. case 2:
  1077. $this->process_form_wordpress_integration();
  1078. break;
  1079. case 3:
  1080. $this->process_form_site_options();
  1081. break;
  1082. case 4:
  1083. $this->process_form_finalise_installation();
  1084. break;
  1085. }
  1086. }
  1087. return true;
  1088. }
  1089. /**
  1090. * Takes inputted form data and injects it into the data array
  1091. *
  1092. * @param integer $step Which steps data to process
  1093. * @return boolean Always returns true
  1094. **/
  1095. function inject_form_values_into_data( $step )
  1096. {
  1097. $data =& $this->data[$step]['form'];
  1098. foreach ( $data as $key => $value ) {
  1099. if ( 'forward_' !== substr( $key, 0, 8 ) && 'back_' !== substr( $key, 0, 5 ) ) {
  1100. if ( isset( $data[$key]['prerequisite'] ) && !$_POST[$data[$key]['prerequisite']] ) {
  1101. if ( isset( $data[$key]['default_value'] ) ) {
  1102. $data[$key]['value'] = $data[$key]['default_value'];
  1103. }
  1104. // do nothing - keep the default value
  1105. } else {
  1106. $data[$key]['value'] = stripslashes_deep( trim( $_POST[$key] ) );
  1107. }
  1108. }
  1109. }
  1110. return true;
  1111. }
  1112. /**
  1113. * Validates the supplied config file data and writes it to the config file.
  1114. *
  1115. * @return void
  1116. **/
  1117. function process_form_config_file()
  1118. {
  1119. $this->inject_form_values_into_data( 1 );
  1120. $data =& $this->data[1]['form'];
  1121. if ( 'en_US' == $data['bb_lang']['value'] ) {
  1122. $data['bb_lang']['value'] = '';
  1123. }
  1124. if ( $data['toggle_1']['value'] ) {
  1125. $data['toggle_1']['checked'] = 'checked="checked"';
  1126. $data['toggle_1']['display'] = 'block';
  1127. // Deal with slashes in the keys
  1128. //$data['bb_auth_key']['value'] = addslashes( stripslashes( $data['bb_auth_key']['value'] ) );
  1129. //$data['bb_secure_auth_key']['value'] = addslashes( stripslashes( $data['bb_secure_auth_key']['value'] ) );
  1130. //$data['bb_logged_in_key']['value'] = addslashes( stripslashes( $data['bb_logged_in_key']['value'] ) );
  1131. //$data['bb_nonce_key']['value'] = addslashes( stripslashes( $data['bb_nonce_key']['value'] ) );
  1132. }
  1133. $requested_prefix = $data['bb_table_prefix']['value'];
  1134. $data['bb_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['bb_table_prefix']['value'] );
  1135. if ( $requested_prefix !== $data['bb_table_prefix']['value'] ) {
  1136. $data['toggle_1']['checked'] = 'checked="checked"';
  1137. $data['toggle_1']['display'] = 'block';
  1138. $this->step_status[1] = 'incomplete';
  1139. $this->strings[1]['messages']['error'][] = __( 'The table prefix can only contain letters, numbers and underscores.<br />Please review the suggestion below.' );
  1140. $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; Based on your input the following prefix is suggested.' );
  1141. return 'incomplete';
  1142. }
  1143. if ( empty( $data['bb_table_prefix']['value'] ) ) {
  1144. $data['bb_table_prefix']['value'] = 'bb_';
  1145. $data['toggle_1']['checked'] = 'checked="checked"';
  1146. $data['toggle_1']['display'] = 'block';
  1147. $this->step_status[1] = 'incomplete';
  1148. $this->strings[1]['messages']['error'][] = __( 'The table prefix can not be blank.<br />Please review the suggestion below.' );
  1149. $this->strings[1]['form_errors']['bb_table_prefix'][] = __( '&bull; The default prefix has been inserted.' );
  1150. return 'incomplete';
  1151. }
  1152. // Stop here if we are going backwards
  1153. if ( $_POST['back_1_1'] ) {
  1154. $this->step_status[1] = 'incomplete';
  1155. return 'incomplete';
  1156. }
  1157. // Test the db connection.
  1158. define( 'BBDB_NAME', $data['bbdb_name']['value'] );
  1159. define( 'BBDB_USER', $data['bbdb_user']['value'] );
  1160. define( 'BBDB_PASSWORD', $data['bbdb_password']['value'] );
  1161. define( 'BBDB_HOST', $data['bbdb_host']['value'] );
  1162. define( 'BBDB_CHARSET', $data['bbdb_charset']['value'] );
  1163. define( 'BBDB_COLLATE', $data['bbdb_collate']['value'] );
  1164. // We'll fail here if the values are no good.
  1165. require_once( BACKPRESS_PATH . 'class.bpdb-multi.php' );
  1166. $bbdb =& new BPDB_Multi( array(
  1167. 'name' => BBDB_NAME,
  1168. 'user' => BBDB_USER,
  1169. 'password' => BBDB_PASSWORD,
  1170. 'host' => BBDB_HOST,
  1171. 'charset' => defined( 'BBDB_CHARSET' ) ? BBDB_CHARSET : false,
  1172. 'collate' => defined( 'BBDB_COLLATE' ) ? BBDB_COLLATE : false,
  1173. 'errors' => 'suppress'
  1174. ) );
  1175. if ( !$bbdb->db_connect( 'SHOW TABLES;' ) ) {
  1176. $bbdb->suppress_errors( false );
  1177. $this->step_status[1] = 'incomplete';
  1178. $this->strings[1]['messages']['error'][] = __( 'There was a problem connecting to the database you specified.<br />Please check the settings, then try again.' );
  1179. return 'error';
  1180. }
  1181. $bbdb->suppress_errors( false );
  1182. $config_result = $this->write_lines_to_file(
  1183. BB_PATH . 'bb-config-sample.php',
  1184. BB_PATH . 'bb-config.php',
  1185. array(
  1186. "define( 'BBDB_NAME'," => array( "'bbpress'", "'" . $data['bbdb_name']['value'] . "'" ),
  1187. "define( 'BBDB_USER'," => array( "'username'", "'" . $data['bbdb_user']['value'] . "'" ),
  1188. "define( 'BBDB_PASSWO" => array( "'password'", "'" . $data['bbdb_password']['value'] . "'" ),
  1189. "define( 'BBDB_HOST'," => array( "'localhost'", "'" . $data['bbdb_host']['value'] . "'" ),
  1190. "define( 'BBDB_CHARSE" => array( "'utf8'", "'" . $data['bbdb_charset']['value'] . "'" ),
  1191. "define( 'BBDB_COLLAT" => array( "''", "'" . $data['bbdb_collate']['value'] . "'" ),
  1192. //"define( 'BB_AUTH_KEY" => array( "'put your unique phrase here'", "'" . $data['bb_auth_key']['value'] . "'" ),
  1193. //"define( 'BB_SECURE_A" => array( "'put your unique phrase here'", "'" . $data['bb_secure_auth_key']['value'] . "'" ),
  1194. //"define( 'BB_LOGGED_I" => array( "'put your unique phrase here'", "'" . $data['bb_logged_in_key']['value'] . "'" ),
  1195. //"define( 'BB_NONCE_KE" => array( "'put your unique phrase here'", "'" . $data['bb_nonce_key']['value'] . "'" ),
  1196. "\$bb_table_prefix = '" => array( "'bb_'", "'" . $data['bb_table_prefix']['value'] . "'" ),
  1197. "define( 'BB_LANG', '" => array( "''", "'" . $data['bb_lang']['value'] . "'" )
  1198. )
  1199. );
  1200. switch ( $config_result ) {
  1201. case -1:
  1202. $this->step_status[1] = 'error';
  1203. $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.' );
  1204. return 'error';
  1205. break;
  1206. case 1:
  1207. $this->configs['bb-config.php'] = BB_PATH . 'bb-config.php';
  1208. $this->step_status[1] = 'complete';
  1209. $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.' );
  1210. break;
  1211. default:
  1212. // Just write the contents to screen
  1213. $this->data[1]['form']['config']['value'] = $config_result;
  1214. $this->step_status[1] = 'manual';
  1215. $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.' );
  1216. break;
  1217. }
  1218. }
  1219. /**
  1220. * Validates the WordPress integration settings
  1221. *
  1222. * @return void
  1223. **/
  1224. function process_form_wordpress_integration()
  1225. {
  1226. // Check the referer
  1227. bb_check_admin_referer( 'bbpress-installer' );
  1228. $this->inject_form_values_into_data( 2 );
  1229. $data =& $this->data[2]['form'];
  1230. // If there are no settings then goto step 3
  1231. if ( !$data['toggle_2_0']['value'] && !$_POST['back_2_1'] ) {
  1232. $this->step_status[2] = 'complete';
  1233. $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.' );
  1234. return 'complete';
  1235. }
  1236. // If integration is selected
  1237. if ( $data['toggle_2_0']['value'] ) {
  1238. $data['toggle_2_0']['checked'] = 'checked="checked"';
  1239. $data['toggle_2_0']['display'] = 'block';
  1240. $data['forward_2_0']['value'] = $data['toggle_2_0']['toggle_value']['on_value'];
  1241. if ( $data['toggle_2_1']['value'] ) {
  1242. $data['toggle_2_1']['checked'] = 'checked="checked"';
  1243. $data['toggle_2_1']['display'] = 'block';
  1244. // Check the wp_siteurl URL for errors
  1245. $data['wp_siteurl']['value'] = $data['wp_siteurl']['value'] ? rtrim( $data['wp_siteurl']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
  1246. $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $data['wp_siteurl']['value'] ) ? 'empty' : false;
  1247. if ( $parsed = parse_url( $data['wp_siteurl']['value'] ) ) {
  1248. $this->strings[2]['form_errors']['wp_siteurl'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
  1249. $this->strings[2]['form_errors']['wp_siteurl'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
  1250. } else {
  1251. $this->strings[2]['form_errors']['wp_siteurl'][] = 'urlparse';
  1252. }
  1253. // Check the wp_home URL for errors
  1254. $data['wp_home']['value'] = $data['wp_home']['value'] ? rtrim( $data['wp_home']['value'], " \t\n\r\0\x0B/" ) . '/' : '';
  1255. $this->strings[2]['form_errors']['wp_home'][] = empty( $data['wp_home']['value'] ) ? 'empty' : false;
  1256. if ( $parsed = parse_url( $data['wp_home']['value'] ) ) {
  1257. $this->strings[2]['form_errors']['wp_home'][] = preg_match( '/https?/i', $parsed['scheme'] ) ? false : 'urlscheme';
  1258. $this->strings[2]['form_errors']['wp_home'][] = empty( $parsed['host'] ) ? 'urlhost' : false;
  1259. } else {
  1260. $this->strings[2]['form_errors']['wp_home'][] = 'urlparse';
  1261. }
  1262. // Deal with slashes in the keys
  1263. $data['wp_auth_key']['value'] = addslashes( stripslashes( $data['wp_auth_key']['value'] ) );
  1264. $data['wp_auth_salt']['value'] = addslashes( stripslashes( $data['wp_auth_salt']['value'] ) );
  1265. $data['wp_secure_auth_key']['value'] = addslashes( stripslashes( $data['wp_secure_auth_key']['value'] ) );
  1266. $data['wp_secure_auth_salt']['value'] = addslashes( stripslashes( $data['wp_secure_auth_salt']['value'] ) );
  1267. $data['wp_logged_in_key']['value'] = addslashes( stripslashes( $data['wp_logged_in_key']['value'] ) );
  1268. $data['wp_logged_in_salt']['value'] = addslashes( stripslashes( $data['wp_logged_in_salt']['value'] ) );
  1269. // Check the keys for errors
  1270. $this->strings[2]['form_errors']['wp_auth_key'][] = empty( $data['wp_auth_key']['value'] ) ? 'empty' : false;
  1271. $this->strings[2]['form_errors']['wp_secure_auth_key'][] = empty( $data['wp_secure_auth_key']['value'] ) ? 'empty' : false;
  1272. $this->strings[2]['form_errors']['wp_logged_in_key'][] = empty( $data['wp_logged_in_key']['value'] ) ? 'empty' : false;
  1273. // Salts can be taken from the database if specified
  1274. if ( !$data['toggle_2_2']['value'] ) {
  1275. $this->strings[2]['form_errors']['wp_auth_salt'][] = empty( $data['wp_auth_salt']['value'] ) ? 'empty' : false;
  1276. // NB; secure_auth_salt is not always set in WordPress
  1277. $this->strings[2]['form_errors']['wp_logged_in_salt'][] = empty( $data['wp_logged_in_salt']['value'] ) ? 'empty' : false;
  1278. }
  1279. }
  1280. // If database integration is selected
  1281. if ( $data['toggle_2_2']['value'] ) {
  1282. $data['toggle_2_2']['checked'] = 'checked="checked"';
  1283. $data['toggle_2_2']['display'] = 'block';
  1284. // Make the wp_table_prefix valid
  1285. $data['wp_table_prefix']['value'] = preg_replace( '/[^0-9a-zA-Z_]/', '', $data['wp_table_prefix']['value'] );
  1286. $data['wp_table_…

Large files files are truncated, but you can click here to view the full file