Issue #2501835 by kgoel, crowdcg, stefan.r, alexpott, joelpittet, Cottser, akalata, xjm, davidhernandez, YesCT: Remove SafeMarkup::set in Drupal\Core\Database\Install\Tasks::runTasks() and ensure multiple messages are printed

8.0.x
Nathaniel Catchpole 2015-08-10 16:02:44 +01:00
parent db37224c30
commit 7fa232d817
7 changed files with 127 additions and 72 deletions

View File

@ -6,7 +6,6 @@ use Drupal\Core\DrupalKernel;
use Drupal\Core\Config\BootstrapConfigStorageFactory;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\Install\TaskException;
use Drupal\Core\Form\FormState;
use Drupal\Core\Installer\Exception\AlreadyInstalledException;
use Drupal\Core\Installer\Exception\InstallerException;
@ -1133,14 +1132,24 @@ function install_database_errors($database, $settings_file) {
// Run tasks associated with the database type. Any errors are caught in the
// calling function.
Database::addConnectionInfo('default', 'default', $database);
try {
db_run_tasks($driver);
}
catch (TaskException $e) {
$errors = db_installer_object($driver)->runTasks();
if (count($errors)) {
$error_message = [
'#type' => 'inline_template',
'#template' => '{% trans %}Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="https://www.drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider.{% endtrans%}{{ errors }}',
'#context' => [
'errors' => [
'#theme' => 'item_list',
'#items' => $errors,
],
],
];
// 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[$driver . '][0'] = $e->getMessage();
$errors[$driver . '][0'] = \Drupal::service('renderer')->renderPlain($error_message);
}
}
return $errors;

View File

@ -1068,19 +1068,6 @@ function install_profile_info($profile, $langcode = 'en') {
return $cache[$profile][$langcode];
}
/**
* Ensures the environment for a Drupal database on a predefined connection.
*
* This will run tasks that check that Drupal can perform all of the functions
* on a database, that Drupal needs. Tasks include simple checks like CREATE
* TABLE to database specific functions like stored procedures and client
* encoding.
*/
function db_run_tasks($driver) {
db_installer_object($driver)->runTasks();
return TRUE;
}
/**
* Returns a database installer object.
*

View File

@ -1,13 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\Database\Install\TaskException.
*/
namespace Drupal\Core\Database\Install;
/**
* Exception thrown if the database installer fails.
*/
class TaskException extends \RuntimeException { }

View File

@ -7,7 +7,6 @@
namespace Drupal\Core\Database\Install;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Database\Database;
/**
@ -128,6 +127,9 @@ abstract class Tasks {
/**
* Run database tasks and tests to see if Drupal can run on the database.
*
* @return array
* A list of error messages.
*/
public function runTasks() {
// We need to establish a connection before we can run tests.
@ -143,21 +145,15 @@ abstract class Tasks {
}
}
else {
throw new TaskException(t("Failed to run all tasks against the database server. The task %task wasn't found.", array('%task' => $task['function'])));
$this->fail(t("Failed to run all tasks against the database server. The task %task wasn't found.", array('%task' => $task['function'])));
}
}
}
// Check for failed results and compile message
$message = '';
foreach ($this->results as $result => $success) {
if (!$success) {
$message = SafeMarkup::isSafe($result) ? $result : SafeMarkup::checkPlain($result);
}
}
if (!empty($message)) {
$message = SafeMarkup::set('Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="https://www.drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider.' . $message);
throw new TaskException($message);
}
// Filter out the success messages from results.
$errors = array_filter($this->results, function ($value) {
return !$value;
});
return array_keys($errors);
}
/**

View File

@ -138,33 +138,33 @@ abstract class InstallerTestBase extends WebTestBase {
// Configure site.
$this->setUpSite();
// Import new settings.php written by the installer.
$request = Request::createFromGlobals();
$class_loader = require $this->container->get('app.root') . '/autoload.php';
Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
if ($this->isInstalled) {
// Import new settings.php written by the installer.
$request = Request::createFromGlobals();
$class_loader = require $this->container->get('app.root') . '/autoload.php';
Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
// After writing settings.php, the installer removes write permissions
// from the site directory. To allow drupal_generate_test_ua() to write
// a file containing the private key for drupal_valid_test_ua(), the site
// directory has to be writable.
// WebTestBase::tearDown() will delete the entire test site directory.
// Not using File API; a potential error must trigger a PHP warning.
chmod($this->container->get('app.root') . '/' . $this->siteDirectory, 0777);
$this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
$this->kernel->prepareLegacyRequest($request);
$this->container = $this->kernel->getContainer();
// Manually configure the test mail collector implementation to prevent
// tests from sending out e-mails and collect them in state instead.
$this->container->get('config.factory')
->getEditable('system.mail')
->set('interface.default', 'test_mail_collector')
->save();
}
// After writing settings.php, the installer removes write permissions
// from the site directory. To allow drupal_generate_test_ua() to write
// a file containing the private key for drupal_valid_test_ua(), the site
// directory has to be writable.
// WebTestBase::tearDown() will delete the entire test site directory.
// Not using File API; a potential error must trigger a PHP warning.
chmod($this->container->get('app.root') . '/' . $this->siteDirectory, 0777);
$this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
$this->kernel->prepareLegacyRequest($request);
$this->container = $this->kernel->getContainer();
$config = $this->container->get('config.factory');
// Manually configure the test mail collector implementation to prevent
// tests from sending out e-mails and collect them in state instead.
$config->getEditable('system.mail')
->set('interface.default', 'test_mail_collector')
->save();
$this->isInstalled = TRUE;
}
/**
@ -196,11 +196,14 @@ abstract class InstallerTestBase extends WebTestBase {
}
/**
* Installer step: Configure site.
* Final installer step: Configure site.
*/
protected function setUpSite() {
$edit = $this->translatePostValues($this->parameters['forms']['install_configure_form']);
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
// If we've got to this point the site is installed using the regular
// installation workflow.
$this->isInstalled = TRUE;
}
/**

View File

@ -0,0 +1,46 @@
<?php
/**
* @file
* Contains \Drupal\system\Tests\Installer\InstallerDatabaseErrorMessagesTest.
*/
namespace Drupal\system\Tests\Installer;
use Drupal\Core\Database\Database;
use Drupal\simpletest\InstallerTestBase;
/**
* Tests the installer with database errors.
*
* @group Installer
*/
class InstallerDatabaseErrorMessagesTest extends InstallerTestBase {
/**
* @{inheritdoc}
*/
protected function setUpSettings() {
// We are creating a table here to force an error in the installer because
// it will try and create the drupal_install_test table as this is part of
// the standard database tests performed by the installer in
// Drupal\Core\Database\Install\Tasks.
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
parent::setUpSettings();
}
/**
* @{inheritdoc}
*/
protected function setUpSite() {
// This step should not appear as we had a failure on the settings screen.
}
/**
* Verifies that the error message in the settings step is correct.
*/
public function testSetUpSettingsErrorMessage() {
$this->assertRaw('<ul><li>Failed to <strong>CREATE</strong> a test table');
}
}

View File

@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Installer;
use Drupal\Core\Database\Database;
use Drupal\simpletest\InstallerTestBase;
use Drupal\user\Entity\User;
@ -45,6 +46,26 @@ class InstallerTranslationTest extends InstallerTestBase {
$this->assertEqual($direction, 'ltr');
}
/**
* @{inheritdoc}
*/
protected function setUpSettings() {
// We are creating a table here to force an error in the installer because
// it will try and create the drupal_install_test table as this is part of
// the standard database tests performed by the installer in
// Drupal\Core\Database\Install\Tasks.
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
parent::setUpSettings();
// Ensure that the error message translation is working.
$this->assertRaw('Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter.');
$this->assertRaw('<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl <em class="placeholder">CREATE TABLE {drupal_install_test} (id int NULL)</em> fehlgeschlagen.');
// Now do it successfully.
Database::getConnection('default')->query('DROP TABLE {drupal_install_test}');
parent::setUpSettings();
}
/**
* Verifies the expected behaviors of the installation result.
*/
@ -127,6 +148,12 @@ msgstr "Save and continue $langcode"
msgid "Anonymous"
msgstr "Anonymous $langcode"
msgid "Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="https://www.drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider."
msgstr "Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter."
msgid "Failed to <strong>CREATE</strong> a test table on your database server with the command %query. The server reports the following message: %error.<p>Are you sure the configured username has the necessary permissions to create tables in the database?</p>"
msgstr "<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl %query fehlgeschlagen."
ENDPO;
}