Source for file index.php
Documentation is available at index.php
* This is the main install menu
* IF YOU ARE READING THIS IN YOUR WEB BROWSER, IT MEANS THAT PHP IS NOT PROPERLY INSTALLED
* ON YOUR WEB SERVER. IF YOU DON'T KNOW WHAT THIS MEANS, CONTACT YOUR SERVER ADMINISTRATOR
* OR YOUR HOSTING COMPANY.
* Quam Plures - {@link http://quamplures.net/}
* Released under GNU GPL License - {@link http://quamplures.net/license.html}
* @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}
* @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
* include config and default functions:
require_once dirname(__FILE__ ). '/../qp_config/_config.php';
// Make the includes believe they are being called in the right place...
define( 'QP_MAIN_INIT', true );
* Define that we're in the install process.
define( 'QP_IS_INSTALLING', true );
$script_start_time = time();
$localtimenow = $script_start_time; // used e.g. for post_datemodified (sample posts)
if( ! $app_config_is_done )
{ // Base config is not done yet, try to guess some values needed for correct display:
require_once $inc_path. '_core/_class'. floor(PHP_VERSION). '.funcs.php';
require_once $inc_path. '_core/_misc.funcs.php';
$Debuglog = new Log( 'note' );
$Messages = new Log('error');
require_once $conf_path. '_upgrade.php';
require_once $inc_path. '_vars.inc.php';
load_funcs('collections/model/_category.funcs.php');
require_once dirname(__FILE__ ). '/_functions_install.php';
$Timer = new Timer('main');
param( 'action', 'string', 'default' );
// Load all available locale defintions:
param( 'locale', 'string' );
if( preg_match('/[a-z]{2}-[A-Z]{2}(-.{1,14})?/', $locale) )
$default_locale = $locale;
// Activate default locale:
{ // Could not activate locale (non-existent?), fallback to en-US:
$default_locale = 'en-US';
* How many sample entries do we have?
* @see installer_timestamp()
// count sample posts (will include 2 that are not timestamped items)
'installer_timestamp()' );
require ( $templates_path. '/_contributors.php' );
$count_contribs = count( $_hic_sunt_dracones );
// calculate how far back to start the installation
$timestamp = ( time() - ( ( $count_samples + $count_contribs ) * 86400 ) );
$title = T_('Upgrade from a previous version');
require_once dirname(__FILE__ ). '/_automated.php';
if( !param( 'conf_admin_login', 'string' ) )
$msg[] = T_('Please enter a login to use for your admin account' );
if( !param( 'conf_admin_pass', 'string' ) )
$msg[] = T_('We strongly advise you choose a password' );
if( !param( 'conf_admin_email', 'string' ) )
$msg[] = T_('Your email is needed in case you forget your password ;)' );
$title = T_('Try again!');
$title = T_('New Install');
$title = sprintf( /* TRANS: %s: Application name */ T_('Delete %s tables'), $app_name );
$title = T_('Base configuration');
header('Content-Type: text/html; charset='. $io_charset);
header('Cache-Control: no-cache'); // no request to this page should get cached!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
printf( /* TRANS: %s: Application name */ T_('%s installer'), $app_name );
<link rel="icon" href="../favicon.ico" type="image/x-icon"/>
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon"/>
<meta name="viewport" content="width = 750" />
<link href="../qp_rsc/css/support_install.css" rel="stylesheet" type="text/css" />
<?php echo T_('Current installation') ?>:
<a href="index.php?locale= <?php echo $default_locale ?>"> <?php echo T_('Install menu') ?></a>
if( $app_config_is_done || (($action != 'start') && ($action != 'default') && ($action != 'conf')) )
$tmp_db_config = $app_db_config;
// We want a friendly message if we can't connect:
$tmp_db_config['halt_on_error'] = false;
$tmp_db_config['show_errors'] = false;
// Make sure we use the proper charset:
$tmp_db_config['connection_charset'] = $evo_charset;
$DB = new DB( $tmp_db_config );
echo '<div class="error"><p class="error">'. T_('Check your database config settings below and update them if necessary...'). '</p></div>';
$DB->halt_on_error = true; // From now on, halt on errors.
$DB->show_errors = true; // From now on, show errors (they're helpful in case of errors!).
$mysql_version = $DB->get_var( 'SELECT VERSION()' );
list ( $mysl_version_main, $mysl_version_minor ) = explode( '.', $mysql_version );
if( ($mysl_version_main * 100 + $mysl_version_minor) < 500 )
die( '<div class="error"><p class="error"><strong>'
. sprintf( T_('The minimum requirement for this version of %s is %s version %s '
. 'but you are trying to use version %s!'),
$app_name, 'MySQL', '5.0', $mysql_version )
. '</strong></p></div>' );
if( ($version_main * 100 + $version_minor) < 500 )
die( '<div class="error"><p class="error"><strong>'
. sprintf( T_( 'The minimum requirement for this version of %s is %s version %s but you are '
. 'trying to use version %s!'),
. '</strong></p></div>' );
// Check other dependencies:
// TODO: Non-install/upgrade-actions should be allowed (e.g. "deletedb")
echo '<div class="error">';
echo '<p class="error"><strong>';
printf( T_('%s cannot be installed because of the following errors:'), $app_name );
echo '<ul class="error"><li>'. implode( '</li><li>', $req_errors ). '</li></ul>';
param( 'conf_db_user', 'string', true );
param( 'conf_db_password', '', true );
param( 'conf_db_name', 'string', true );
param( 'conf_db_host', 'string', true );
param( 'conf_db_tableprefix', 'string', $app_db_tableprefix );
param( 'conf_baseurl', 'string', true );
$conf_baseurl = preg_replace( '#(/)?$#', '', $conf_baseurl ). '/'; // force trailing slash
'password' => $conf_db_password,
'aliases' => $app_db_config['aliases'],
'use_transactions' => $app_db_config['use_transactions'],
'table_options' => $app_db_config['table_options'],
'connection_charset' => $app_db_config['connection_charset'],
'halt_on_error' => false )
echo '<p class="error">'. T_('It seems that the database config settings you entered don\'t work. Please check them carefully and try again...'). '</p>';
$conf_template_filepath = $conf_path. '_main_config.template.php';
$conf_filepath = $conf_path. '_main_config.php';
$file_loaded = @file( $conf_template_filepath );
if( empty( $file_loaded ) )
{ // This should actually never happen, just in case...
echo '<div class="error"><p class="error">'. sprintf( T_('Could not load original conf file [%s]. Is it missing?'), $conf_filepath ). '</p></div>';
$conf = implode( '', $file_loaded );
'#\$app_db_config\s*=\s*array\(
\s*[\'"]host[\'"]\s*=>\s*[\'"].*?[\'"], ([^\n\r]*\r?\n)
\s*[\'"]name[\'"]\s*=>\s*[\'"].*?[\'"], ([^\n\r]*\r?\n)
\s*[\'"]user[\'"]\s*=>\s*[\'"].*?[\'"], ([^\n\r]*\r?\n)
\s*[\'"]password[\'"]\s*=>\s*[\'"].*?[\'"], ([^\n\r]*\r?\n)
"#app_db_tableprefix\s*=\s*'.*?';#",
"#app_baseurl\s*=\s*'.*?';#",
"#app_config_is_done\s*=.*?;#",
"\$app_db_config = array(\n"
. "\t'host' => '". str_replace( "'", "\'", $conf_db_host ). "',\$1"
. "\t'name' => '". str_replace( "'", "\'", $conf_db_name ). "',\$2"
. "\t'user' => '". str_replace( "'", "\'", $conf_db_user ). "',\$3"
. "\t'password' => '". str_replace( "'", "\'", $conf_db_password ). "',\$4",
"app_db_tableprefix = '". str_replace( "'", "\'", $conf_db_tableprefix ). "';",
"app_baseurl = '". str_replace( "'", "\'", $conf_baseurl ). "';",
'app_config_is_done = 1;',
$f = @fopen( $conf_filepath , 'w' );
<h1> <?php echo T_('Config file update') ?></h1>
<p><strong> <?php printf( T_('We cannot automatically create or update your config file [%s]!'), $conf_filepath ); ?></strong></p>
<p><strong> <?php echo T_('You need to update the config file manually:') ?></strong></p>
<li> <?php echo T_('Create a new text file with a text editor.') ?></li>
<li> <?php echo T_('Copy the contents from the box below.') ?></li>
<li> <?php echo T_('Paste them into your local text editor. <strong>ATTENTION: make sure there is ABSOLUTELY NO WHITESPACE after the final <code>?></code> in the file.</strong> Any space, tab, newline or blank line at the end of the conf file may prevent cookies from being set when you try to log in later.') ?></li>
<li> <?php echo T_('Save the file locally under the name <code>_main_config.php</code>') ?></li>
<li> <?php echo T_('Upload the file to your server, into the <code>/qp_config</code> folder.') ?></li>
<li> <?php printf( T_('When done <a %s>call the installer</a> again. The installer will rerun tests to connect to your database.'), 'href="index.php?locale='. $default_locale. '"') ?></li>
<p> <?php echo T_('This is how your _main_config.php should look like:') ?></p>
printf( '<div class="success"><p>'. T_('Your configuration file [%s] has been successfully created.'). '</p></div>', $conf_filepath );
$app_db_tableprefix = $conf_db_tableprefix;
$app_baseurl = $conf_baseurl;
// ATTENTION: we continue here...
/* Start of install procedure */
if( $action == 'start' || !$app_config_is_done )
printf( '<img src="../qp_rsc/img/qp-logo.jpg" alt="'. T_('%s Logo'). '" title="'. T_('%s Logo'). '"/>', $app_name, $app_name );
echo '<h1>'. T_('Base configuration'). '</h1>';
if( $app_config_is_done && $app_allow_dbase_reset != 1 )
echo '<p><strong>'. T_('Resetting the base configuration is currently disabled for security reasons.'). '</strong></p>';
echo '<p>'. sprintf( T_('To enable it, please go to the %s file and change: %s to %s'), '/qp_config/_main_config.php', '<pre>$app_allow_dbase_reset = 0;</pre>', '<pre>$app_allow_dbase_reset = 1;</pre>' ). '</p>';
echo '<p>'. T_('Then <strong>reload this page</strong> and a reset option will appear.'). '</p>';
// Set default params if not provided otherwise:
param( 'conf_db_user', 'string', $app_db_config['user'] );
param( 'conf_db_password', '', $app_db_config['password'] );
param( 'conf_db_name', 'string', $app_db_config['name'] );
param( 'conf_db_host', 'string', $app_db_config['host'] );
param( 'conf_db_tableprefix', 'string', $app_db_tableprefix );
$app_baseurl = 'http://'. ( isset ( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : 'yourserver.com' );
if( isset ( $_SERVER['SERVER_PORT'] ) && ( $_SERVER['SERVER_PORT'] != '80' ) && (strpos($app_baseurl,':') === false) )
$app_baseurl .= ':'. $_SERVER['SERVER_PORT'];
$app_baseurl .= preg_replace( '#/qp_install(/(index.php)?)?$#', '', $ReqPath ). '/';
param( 'conf_baseurl', 'string', $app_baseurl );
<p> <?php echo T_('The basic configuration file (<code>/qp_config/_main_config.php</code>) has not been created yet. If your server supports it, you can automatically generate it by filling out the form below.') ?></p>
<p> <?php printf( T_('This is the minimum info we need to set up %s on this server:'), $app_name ); ?></p>
<form class="fform" name="form" action="index.php" method="post">
<input type="hidden" name="action" value="conf" />
<input type="hidden" name="locale" value=" <?php echo $default_locale; ?>" />
<legend> <?php echo T_('Blog settings') ?></legend>
form_text( 'conf_baseurl', $conf_baseurl, 50, T_('Website address'),
sprintf( /* TRANS: %1$s: App name */
T_('This is where %1$s and your blogs reside by default. '
. 'CHECK THIS CAREFULLY or not much will work. If you want to '
. 'test %1$s on your local machine, in order for login cookies '
. 'to work, you MUST use http://<strong>localhost</strong>/path... '
. 'Do NOT use your machine\'s name!' ), $app_name ),
<legend> <?php echo T_('Database you want to install into') ?></legend>
printf( /* TRANS: %1$s: App name. */
T_( '%1$s stores blog posts, comments, user permissions, etc. in a MySQL '
. 'database. You must create this database prior to installing %1$s '
. 'and provide the access parameters to this database below. If '
. 'you are not familiar with this, you can ask your hosting provider '
. 'to create the database for you.' ), $app_name );
form_text( 'conf_db_host', $conf_db_host, 16, T_('MySQL Host/Server'), T_( 'Typically looks like "localhost" or "sql-6" or "sql-8.yourhost.net"...' ), 120 );
form_text( 'conf_db_name', $conf_db_name, 16, T_('MySQL Database'), T_( 'Name of the MySQL database you have created on the server' ), 100);
form_text( 'conf_db_user', $conf_db_user, 16, T_('MySQL Username'), sprintf( T_('Used by %s to access the MySQL database' ), $app_name ), 100 );
form_text( 'conf_db_password', $conf_db_password, 16, T_('MySQL Password'), sprintf( T_('Used by %s to access the MySQL database' ), $app_name ), 100 ); // no need to hide this. nobody installs an application from a public place
form_text( 'conf_db_tableprefix', $conf_db_tableprefix, 16, T_('MySQL tables prefix'), sprintf( T_('All DB tables will be prefixed with this. You need to change this only if you want to have multiple %s installations in the same DB.' ), $app_name ), 30 );
<input type="submit" name="submit" value=" <?php echo T_('Update config file') ?>" class="search" />
<input type="reset" value=" <?php echo T_('Reset') ?>" class="search" />
// if config was already done, move on to main menu:
param('conf_admin_login', 'string' );
param('conf_admin_pass', 'string' );
param('conf_admin_email', 'string' );
printf( '<img src="../qp_rsc/img/qp-logo.jpg" alt="'. T_('%s Logo'). '" title="'. T_('%s Logo'). '"/>', $app_name, $app_name );
<h1> <?php printf( T_('Install %s version %s'), $app_name, $app_version ); ?></h1>
<form action="index.php" method="post">
<input type="hidden" name="locale" value=" <?php echo $default_locale ?>" />
<input type="hidden" name="confirmed" value="0" />
<input type="hidden" name="installer_version" value="10" />
<div id="op-newdb" class="op-group">
<input type="radio" name="action" id="newdb" value="newdb"
* @todo (legacy): fp> change the above to 'newdbsettings' for an additional settings screen. ASDFGHJKL
// @todo (test): this todo tag probably won't work ASDFGHJKL
echo ' checked="checked" />';
<label for="newdb" class="option"> <?php
printf( T_('<strong>New Install</strong>: Install %s database tables.'), $app_name );
<h3> <?php echo T_('Admin account details' ); ?></h3>
echo '<p class="error">'. implode( '<br />', $msg ). '</p>';
form_text( 'conf_admin_login', $conf_admin_login, 50, T_('Login'), T_('This will be used to create your admin account.' ), 80 );
form_text( 'conf_admin_pass', $conf_admin_pass, 50, T_('Password'), T_('We advise you use a strong password' ), 80 );
form_text( 'conf_admin_email', $conf_admin_email, 50, T_('Your email'), T_('This will be used to receive notifications for comments on your blog, etc.' ), 80 );
<h3> <?php echo T_('Example posts' ); ?></h3>
<input type="checkbox" name="create_sample_contents" id="create_sample_contents" value="1" checked="checked" />
<label for="create_sample_contents"> <?php
printf( T_('Also install sample blogs & sample contents. The sample posts explain '
. 'several features of %s. This is highly recommended for new users.'),
if( $app_db_version !== NULL )
<div id="op-dbupgrade" class="op-group">
<input type="radio" name="action" id="dbupgrade" value="dbupgrade"
if( !is_null($old_db_version) && $old_db_version < $app_db_version )
echo ' checked="checked" />';
<label for="dbupgrade"> <?php
printf( /* TRANS: %1$s: App name. */ T_('<strong>Upgrade from a previous version of %1$s</strong>'), $app_name );
. '%1$s database tables in order to make them compatible with the current '
. 'version.'), $app_name ). '</p><p class="options">'
. T_('<strong>WARNING:</strong> If you have modified your database, '
. 'this operation may fail. Make sure you have a backup.');
if( $app_allow_dbase_reset == 1 )
<div class="op-deletedb"><input type="radio" name="action" id="deletedb" value="deletedb" />
<label for="deletedb"><strong> <?php printf( T_('Delete %s tables'), $app_name ); ?></strong></label>
printf( /* TRANS: %1$s: App name. */
T_('If you have installed %1$s tables before and wish to start anew, '
. 'you must delete the %1$s tables before you can start a new installation. <br />'
. '<strong>WARNING: All your %1$s tables and data will be lost!!!</strong> '
. 'Any non-%1$s tables will remain untouched though.'), $app_name );
<input type="radio" name="action" id="start" value="start" />
<label for="start"><strong> <?php echo T_('Change your base configuration'); ?></strong></label>
. 'You only want to do this in rare occasions where you may have moved '
. 'your %s files or database to a different location...'), $app_name );
if( $app_allow_dbase_reset != 1 )
echo '<div class="floatright"><a href="index.php?action=deletedb&locale='. $default_locale. '">'. T_('Need to start anew?'). ' »</a></div>';
<input type="submit" value=" <?php echo T_('GO!')?> "
onclick="var dc = document.getElementById( 'deletedb' ); if( dc && dc.checked ) { if ( confirm( ' <?php
printf( /* TRANS: %s gets replaced by app name, usually "quamplures" */ TS_( 'Are you sure you want to delete your existing %s tables?\nDo you have a backup?' ), $app_name );
?>' ) ) { this.form.confirmed.value = 1; return true; } else return false; }" />
* fp> TODO: Add a screen for additionnal settings:
* - create_sample_contents : to be moved away from main screen
* - storage_charset: offer option to FORCE storing data in UTF-8 even if current locale doesn't require it (must be supported by MySQL) -- recommended for multilingual blogs
* - evo_charset: offer option to FORCE handling data internally in UTF-8 even if current locale doesn't require it (requires mbstring) -- not recommended in most situations
* -----------------------------------------------------------------------------------
* NEW DB: install a new Quam Plures database.
* -----------------------------------------------------------------------------------
* Note: auto installers should kick in directly at this step and provide all required params.
// fp> TODO: this test should probably be made more generic and applied to upgrade too.
$expected_connection_charset = $DB->php_to_mysql_charmap($evo_charset);
if( $DB->connection_charset != $expected_connection_charset )
echo '<div class="error"><p class="error">';
printf( T_('In order to install %s with the %s locale, your MySQL needs to support '
. 'the %s connection charset (SET NAMES %s).' ), $app_name, $current_locale,
$evo_charset, $expected_connection_charset );
// sam2kb> TODO: If something is not supported we can display a message saying "do this and that, enable extension X etc. etc... or switch to a better hosting".
* -----------------------------------------------------------------------------------
* DATABASE UPGRADE: Upgrade data from existing Quam Plures database
* -----------------------------------------------------------------------------------
require_once( dirname(__FILE__ ). '/_functions_dbupgrade.php' );
printf( T_('Upgrading data in existing %s database...'), $app_name );
<p> <?php echo T_('Upgrade completed successfully!')?></p>
<p> <?php printf( T_('Now you can <a %s>log in</a> with your usual %s username and password.'), 'href="'. $admin_url. '"', $app_name ); ?></p>
* -----------------------------------------------------------------------------------
* DELETE DB: Delete the db structure!!! (Everything will be lost)
* -----------------------------------------------------------------------------------
require_once( dirname(__FILE__ ). '/_functions_delete.php' );
printf( '<img src="../qp_rsc/img/qp-logo.jpg" alt="'. T_('%s Logo'). '" title="'. T_('%s Logo'). '"/>', $app_name, $app_name );
printf( T_('Deleting %s tables from the datatase...'), $app_name );
if( $app_allow_dbase_reset != 1 )
printf( /* TRANS: %1$s: App name. */
T_('If you have installed %1$s tables before and wish to start anew, you must delete '
. 'the %1$s tables before you can start a new installation. %1$s can delete its '
. 'own tables for you, but for obvious security reasons, this feature is disabled '
. 'by default.'), $app_name );
echo '<p>'. sprintf( T_('To enable it, please go to the %s file and change: %s to %s'), '/qp_config/_main_config.php', '<pre>$app_allow_dbase_reset = 0;</pre>', '<pre>$app_allow_dbase_reset = 1;</pre>' ). '</p>';
echo '<p>'. T_('Then reload this page and a reset option will appear.'). '</p>';
echo '<p><a href="index.php?locale='. $default_locale. '">« '. T_('Back to install menu'). '</a></p>';
if( ! param('confirmed', 'integer', 1) )
echo nl2br( htmlspecialchars( sprintf( /* TRANS: %s gets replaced by app name, usually "quamplures" */ T_( "Are you sure you want to delete your existing %s tables?\nDo you have a backup?" ), $app_name ) ) );
<form class="inline" name="form" action="index.php" method="post">
<input type="hidden" name="action" value="deletedb" />
<input type="hidden" name="confirmed" value="1" />
<input type="hidden" name="locale" value=" <?php echo $default_locale; ?>" />
<input type="submit" value=" <?php echo T_('I am sure!')?> " />
<form class="inline" name="form" action="index.php" method="get">
<input type="hidden" name="locale" value=" <?php echo $default_locale; ?>" />
<input type="submit" value=" <?php echo T_('CANCEL')?> " />
// TODO: fp>> I don't trust the plugins to uninstall themselves correctly. There will be tons of lousy poorly written plugins. All I trust them to do is to crash the uninstall procedure. We want a hardcore brute force uninsall! and most users "may NOT want" to even think about "ma-nu-al-ly" removing something from their DB.
$DB->show_errors = $DB->halt_on_error = false;
$Plugins = new Plugins();
$DB->show_errors = $DB->halt_on_error = true;
$at_least_one_failed = false;
foreach( $Plugins->get_list_by_event( 'Uninstall' ) as $l_Plugin )
$success = $Plugins->call_method( $l_Plugin->ID, 'Uninstall', $params = array( 'unattended' => true ) );
echo "Failed un-installing plugin $l_Plugin->classname (ID $l_Plugin->ID)...<br />\n";
$at_least_one_failed = false;
echo "Uninstalled plugin $l_Plugin->classname (ID $l_Plugin->ID)...<br />\n";
if( $at_least_one_failed )
echo "You may want to manually remove left files or DB tables from the failed plugin(s).<br />\n";
$DB->show_errors = $DB->halt_on_error = true;
<p> <?php echo T_('Reset done!')?></p>
<p><a href="index.php?locale= <?php echo $default_locale ?>">« <?php echo T_('Back to install menu') ?></a></p>
|