summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2010-11-29 02:55:57 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2010-11-29 02:55:57 +0000
commitff119bc0ccfa224279456c901904955a6b1f4d05 (patch)
tree7219f746418770bc7082236f9ddc031ba82042a8 /includes
parent3d353c47fab804d22411bdfa87407b81a4a415c6 (diff)
downloadbrdo-ff119bc0ccfa224279456c901904955a6b1f4d05.tar.gz
brdo-ff119bc0ccfa224279456c901904955a6b1f4d05.tar.bz2
#346494 by hswong3i, Pancho, Dave Reid, duellj, dalin: Fixed DB drivers need to be able to change the configure database form during install
Diffstat (limited to 'includes')
-rw-r--r--includes/database/sqlite/install.inc27
-rw-r--r--includes/install.core.inc123
-rw-r--r--includes/install.inc127
3 files changed, 190 insertions, 87 deletions
diff --git a/includes/database/sqlite/install.inc b/includes/database/sqlite/install.inc
index 82ed0a48d..a8a12410d 100644
--- a/includes/database/sqlite/install.inc
+++ b/includes/database/sqlite/install.inc
@@ -21,5 +21,32 @@ class DatabaseTasks_sqlite extends DatabaseTasks {
public function minimumVersion() {
return '3.3.7';
}
+
+ public function getFormOptions($database) {
+ $form = parent::getFormOptions($database);
+
+ // Remove the options that only apply to client/server style databases.
+ unset($form['username'], $form['password'], $form['advanced_options']['host'], $form['advanced_options']['port']);
+
+ // Make the text more accurate for SQLite.
+ $form['database']['#title'] = st('Database file');
+ $form['database']['#description'] = st('The absolute path to the file where @drupal data will be stored. This must be writable by the web server and should exist outside of the web root.', array('@drupal' => drupal_install_profile_distribution_name()));
+ $default_database = conf_path(FALSE, TRUE) . '/files/.ht.sqlite';
+ $form['database']['#default_value'] = empty($database['database']) ? $default_database : $database['database'];
+ return $form;
+ }
+
+ public function validateDatabaseSettings($database) {
+ // Perform standard validation.
+ $errors = parent::validateDatabaseSettings($database);
+
+ // Verify the database is writable.
+ $db_directory = new SplFileInfo(dirname($database['database']));
+ if (!$db_directory->isWritable()) {
+ $errors[$database['driver'] . '][database'] = st('The directory you specified is not writable by the web server.');
+ }
+
+ return $errors;
+ }
}
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 179d6b84d..5b01eb634 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -850,14 +850,13 @@ function install_settings_form($form, &$form_state, &$install_state) {
drupal_set_title(st('Database configuration'));
- $drivers = drupal_detect_database_types();
+ $drivers = drupal_get_database_types();
$drivers_keys = array_keys($drivers);
$form['driver'] = array(
'#type' => 'radios',
'#title' => st('Database type'),
'#required' => TRUE,
- '#options' => $drivers,
'#default_value' => !empty($database['driver']) ? $database['driver'] : current($drivers_keys),
'#description' => st('The type of database your @drupal data will be stored in.', array('@drupal' => drupal_install_profile_distribution_name())),
);
@@ -866,82 +865,35 @@ function install_settings_form($form, &$form_state, &$install_state) {
$form['driver']['#description'] .= ' ' . st('Your PHP configuration only supports a single database type, so it has been automatically selected.');
}
- // Database name.
- $form['database'] = array(
- '#type' => 'textfield',
- '#title' => st('Database name'),
- '#default_value' => empty($database['database']) ? '' : $database['database'],
- '#size' => 45,
- '#required' => TRUE,
- '#description' => st('The name of the database your @drupal data will be stored in. It must exist on your server before @drupal can be installed.', array('@drupal' => drupal_install_profile_distribution_name())),
- );
-
- // Database username.
- $form['username'] = array(
- '#type' => 'textfield',
- '#title' => st('Database username'),
- '#default_value' => empty($database['username']) ? '' : $database['username'],
- '#size' => 45,
- );
-
- // Database password.
- $form['password'] = array(
- '#type' => 'password',
- '#title' => st('Database password'),
- '#default_value' => empty($database['password']) ? '' : $database['password'],
- '#size' => 45,
- );
-
- $form['advanced_options'] = array(
- '#type' => 'fieldset',
- '#title' => st('Advanced options'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- '#description' => st("These options are only necessary for some sites. If you're not sure what you should enter here, leave the default settings or check with your hosting provider.")
- );
-
- // Database host.
- $form['advanced_options']['host'] = array(
- '#type' => 'textfield',
- '#title' => st('Database host'),
- '#default_value' => empty($database['host']) ? 'localhost' : $database['host'],
- '#size' => 45,
- // Hostnames can be 255 characters long.
- '#maxlength' => 255,
- '#required' => TRUE,
- '#description' => st('If your database is located on a different server, change this.'),
- );
-
- // Database port.
- $form['advanced_options']['port'] = array(
- '#type' => 'textfield',
- '#title' => st('Database port'),
- '#default_value' => empty($database['port']) ? '' : $database['port'],
- '#size' => 45,
- // The maximum port number is 65536, 5 digits.
- '#maxlength' => 5,
- '#description' => st('If your database server is listening to a non-standard port, enter its number.'),
- );
-
- // Table prefix.
- $db_prefix = ($profile == 'standard') ? 'drupal_' : $profile . '_';
- $form['advanced_options']['db_prefix'] = array(
- '#type' => 'textfield',
- '#title' => st('Table prefix'),
- '#default_value' => '',
- '#size' => 45,
- '#description' => st('If more than one application will be sharing this database, enter a table prefix such as %prefix for your @drupal site here.', array('@drupal' => drupal_install_profile_distribution_name(), '%prefix' => $db_prefix)),
- );
+ // Add driver specific configuration options.
+ foreach ($drivers as $key => $driver) {
+ $form['driver']['#options'][$key] = $driver->name();
+
+ $form['settings'][$key] = $driver->getFormOptions($database);
+ $form['settings'][$key]['#prefix'] = '<h2 class="js-hide">' . st('@driver_name settings', array('@driver_name' => $driver->name())) . '</h2>';
+ $form['settings'][$key]['#type'] = 'container';
+ $form['settings'][$key]['#tree'] = TRUE;
+ $form['settings'][$key]['advanced_options']['#parents'] = array($key);
+ $form['settings'][$key]['#states'] = array(
+ 'visible' => array(
+ ':input[name=driver]' => array('value' => $key),
+ )
+ );
+ }
$form['actions'] = array('#type' => 'actions');
$form['actions']['save'] = array(
'#type' => 'submit',
'#value' => st('Save and continue'),
+ '#limit_validation_errors' => array(
+ array('driver'),
+ array(isset($form_state['input']['driver']) ? $form_state['input']['driver'] : current($drivers_keys)),
+ ),
+ '#submit' => array('install_settings_form_submit'),
);
$form['errors'] = array();
$form['settings_file'] = array('#type' => 'value', '#value' => $settings_file);
- $form['_database'] = array('#type' => 'value');
return $form;
}
@@ -950,12 +902,17 @@ function install_settings_form($form, &$form_state, &$install_state) {
* Form API validate for install_settings form.
*/
function install_settings_form_validate($form, &$form_state) {
+ $driver = $form_state['values']['driver'];
+ $database = $form_state['values'][$driver];
+ $database['driver'] = $driver;
+
// TODO: remove when PIFR will be updated to use 'db_prefix' instead of
// 'prefix' in the database settings form.
- $form_state['values']['prefix'] = $form_state['values']['db_prefix'];
+ $database['prefix'] = $database['db_prefix'];
+ unset($database['db_prefix']);
- form_set_value($form['_database'], $form_state['values'], $form_state);
- $errors = install_database_errors($form_state['values'], $form_state['values']['settings_file']);
+ $form_state['storage']['database'] = $database;
+ $errors = install_database_errors($database, $form_state['values']['settings_file']);
foreach ($errors as $name => $message) {
form_set_error($name, $message);
}
@@ -967,22 +924,17 @@ function install_settings_form_validate($form, &$form_state) {
function install_database_errors($database, $settings_file) {
global $databases;
$errors = array();
- // Verify the table prefix.
- if (!empty($database['prefix']) && is_string($database['prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['prefix'])) {
- $errors['prefix'] = st('The database table prefix you have entered, %prefix, is invalid. The table prefix can only contain alphanumeric characters, periods, or underscores.', array('%prefix' => $database['prefix']));
- }
-
- if (!empty($database['port']) && !is_numeric($database['port'])) {
- $errors['db_port'] = st('Database port must be a number.');
- }
// Check database type.
- $database_types = drupal_detect_database_types();
+ $database_types = drupal_get_database_types();
$driver = $database['driver'];
if (!isset($database_types[$driver])) {
- $errors['driver'] = st("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '@drupal' => drupal_install_profile_distribution_name(), '%driver' => $database['driver']));
+ $errors['driver'] = st("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '@drupal' => drupal_install_profile_distribution_name(), '%driver' => $driver));
}
else {
+ // Run driver specific validation
+ $errors += $database_types[$driver]->validateDatabaseSettings($database);
+
// Run tasks associated with the database type. Any errors are caught in the
// calling function.
$databases['default']['default'] = $database;
@@ -991,13 +943,13 @@ function install_database_errors($database, $settings_file) {
Database::parseConnectionInfo();
try {
- db_run_tasks($database['driver']);
+ db_run_tasks($driver);
}
catch (DatabaseTaskException $e) {
// These are generic errors, so we do not have any specific key of the
// database connection array to attach them to; therefore, we just put
// them in the error array with standard numeric keys.
- $errors[] = $e->getMessage();
+ $errors[$driver . '][0'] = $e->getMessage();
}
}
return $errors;
@@ -1009,10 +961,9 @@ function install_database_errors($database, $settings_file) {
function install_settings_form_submit($form, &$form_state) {
global $install_state;
- $database = array_intersect_key($form_state['values']['_database'], array_flip(array('driver', 'database', 'username', 'password', 'host', 'port', 'prefix')));
// Update global settings array and save.
$settings['databases'] = array(
- 'value' => array('default' => array('default' => $database)),
+ 'value' => array('default' => array('default' => $form_state['storage']['database'])),
'required' => TRUE,
);
$settings['drupal_hash_salt'] = array(
diff --git a/includes/install.inc b/includes/install.inc
index 6e0b7dc7b..2c9810a08 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -230,6 +230,22 @@ function drupal_detect_baseurl($file = 'install.php') {
* An array of database types compiled into PHP.
*/
function drupal_detect_database_types() {
+ $databases = drupal_get_database_types();
+
+ foreach ($databases as $driver => $installer) {
+ $databases[$driver] = $installer->name();
+ }
+
+ return $databases;
+}
+
+/**
+ * Return all supported database installer objects that are compiled into PHP.
+ *
+ * @return
+ * An array of database installer objects compiled into PHP.
+ */
+function drupal_get_database_types() {
$databases = array();
// We define a driver as a directory in /includes/database that in turn
@@ -249,7 +265,7 @@ function drupal_detect_database_types() {
$class = 'DatabaseTasks_' . $driver;
$installer = new $class();
if ($installer->installable()) {
- $databases[$driver] = $installer->name();
+ $databases[$driver] = $installer;
}
}
@@ -445,7 +461,116 @@ abstract class DatabaseTasks {
$this->fail(st("The database version %version is less than the minimum required version %minimum_version.", array('%version' => Database::getConnection()->version(), '%minimum_version' => $this->minimumVersion())));
}
}
+
+ /**
+ * Return driver specific configuration options.
+ *
+ * @param $database
+ * An array of driver specific configuration options.
+ *
+ * @return
+ * The options form array.
+ */
+ public function getFormOptions($database) {
+ $form['database'] = array(
+ '#type' => 'textfield',
+ '#title' => st('Database name'),
+ '#default_value' => empty($database['database']) ? '' : $database['database'],
+ '#size' => 45,
+ '#required' => TRUE,
+ '#description' => st('The name of the database your @drupal data will be stored in. It must exist on your server before @drupal can be installed.', array('@drupal' => drupal_install_profile_distribution_name())),
+ );
+
+ $form['username'] = array(
+ '#type' => 'textfield',
+ '#title' => st('Database username'),
+ '#default_value' => empty($database['username']) ? '' : $database['username'],
+ '#required' => TRUE,
+ '#size' => 45,
+ );
+
+ $form['password'] = array(
+ '#type' => 'password',
+ '#title' => st('Database password'),
+ '#default_value' => empty($database['password']) ? '' : $database['password'],
+ '#required' => FALSE,
+ '#size' => 45,
+ );
+
+ $form['advanced_options'] = array(
+ '#type' => 'fieldset',
+ '#title' => st('Advanced options'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#description' => st("These options are only necessary for some sites. If you're not sure what you should enter here, leave the default settings or check with your hosting provider."),
+ '#weight' => 10,
+ );
+
+ $profile = drupal_get_profile();
+ $db_prefix = ($profile == 'standard') ? 'drupal_' : $profile . '_';
+ $form['advanced_options']['db_prefix'] = array(
+ '#type' => 'textfield',
+ '#title' => st('Table prefix'),
+ '#default_value' => '',
+ '#size' => 45,
+ '#description' => st('If more than one application will be sharing this database, enter a table prefix such as %prefix for your @drupal site here.', array('@drupal' => drupal_install_profile_distribution_name(), '%prefix' => $db_prefix)),
+ '#weight' => 10,
+ );
+
+ $form['advanced_options']['host'] = array(
+ '#type' => 'textfield',
+ '#title' => st('Database host'),
+ '#default_value' => empty($database['host']) ? 'localhost' : $database['host'],
+ '#size' => 45,
+ // Hostnames can be 255 characters long.
+ '#maxlength' => 255,
+ '#required' => TRUE,
+ '#description' => st('If your database is located on a different server, change this.'),
+ );
+
+ $form['advanced_options']['port'] = array(
+ '#type' => 'textfield',
+ '#title' => st('Database port'),
+ '#default_value' => empty($database['port']) ? '' : $database['port'],
+ '#size' => 45,
+ // The maximum port number is 65536, 5 digits.
+ '#maxlength' => 5,
+ '#description' => st('If your database server is listening to a non-standard port, enter its number.'),
+ );
+
+ return $form;
+ }
+
+ /**
+ * Validates driver specific configuration settings.
+ *
+ * Checks to ensure correct basic database settings and that a proper
+ * connection to the database can be established.
+ *
+ * @param $database
+ * An array of driver specific configuration options.
+ *
+ * @return
+ * An array of driver configuration errors, keyed by form element name.
+ */
+ public function validateDatabaseSettings($database) {
+ $errors = array();
+
+ // Verify the table prefix.
+ if (!empty($database['prefix']) && is_string($database['prefix']) && !preg_match('/^[A-Za-z0-9_.]+$/', $database['prefix'])) {
+ $errors[$database['driver'] . '][advanced_options][db_prefix'] = st('The database table prefix you have entered, %prefix, is invalid. The table prefix can only contain alphanumeric characters, periods, or underscores.', array('%prefix' => $database['prefix']));
+ }
+
+ // Verify the database port.
+ if (!empty($database['port']) && !is_numeric($database['port'])) {
+ $errors[$database['driver'] . '][advanced_options][port'] = st('Database port must be a number.');
+ }
+
+ return $errors;
+ }
+
}
+
/**
* @class Exception class used to throw error if the DatabaseInstaller fails.
*/