summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreffulgentsia2017-12-03 05:03:36 (GMT)
committereffulgentsia2017-12-03 05:03:36 (GMT)
commit9f26cfb2aed45a6f0ae59dc91f20042d7574dc1e (patch)
treefa5e01b95286c233a924bddb38d0620d8bb51a7c
parentc9678f5979e7af9d395930ed4e2aa8cb260ae6ec (diff)
Issue #2670966 by xjm, Crell, claudiu.cristea, alexpott, timmillwood, rakesh.gectcr, catch, dawehner, David_Rothstein, hchonov, martin107, tstoeckler, andypost, cilefen, RobLoach, Fabianx, salvis, hussainweb, JeroenT, larowlan, pfrenssen, daffie, webchick, wturrell: Warn users of old PHP versions
-rw-r--r--core/includes/bootstrap.inc11
-rw-r--r--core/modules/simpletest/src/InstallerTestBase.php60
-rw-r--r--core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php36
-rw-r--r--core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php34
-rw-r--r--core/modules/system/src/Tests/Installer/InstallerExistingInstallationTest.php1
-rw-r--r--core/modules/system/system.install17
6 files changed, 130 insertions, 29 deletions
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 6c8ee5e..d05298d 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -19,10 +19,21 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Minimum supported version of PHP.
+ *
+ * Drupal cannot be installed on versions of PHP older than this version.
*/
const DRUPAL_MINIMUM_PHP = '5.5.9';
/**
+ * Minimum recommended version of PHP.
+ *
+ * Sites installing Drupal on PHP versions lower than this will see a warning
+ * message, but Drupal can still be installed. Used for (e.g.) PHP versions
+ * that have reached their EOL or will in the near future.
+ */
+const DRUPAL_RECOMMENDED_PHP = '7.1';
+
+/**
* Minimum recommended value of PHP memory_limit.
*
* 64M was chosen as a minimum requirement in order to allow for additional
diff --git a/core/modules/simpletest/src/InstallerTestBase.php b/core/modules/simpletest/src/InstallerTestBase.php
index 92f33dc..96d98e0 100644
--- a/core/modules/simpletest/src/InstallerTestBase.php
+++ b/core/modules/simpletest/src/InstallerTestBase.php
@@ -122,6 +122,9 @@ abstract class InstallerTestBase extends WebTestBase {
// Select profile.
$this->setUpProfile();
+ // Address the requirements problem screen, if any.
+ $this->setUpRequirementsProblem();
+
// Configure settings.
$this->setUpSettings();
@@ -196,6 +199,23 @@ abstract class InstallerTestBase extends WebTestBase {
}
/**
+ * Installer step: Requirements problem.
+ *
+ * Override this method to test specific requirements warnings or errors
+ * during the installer.
+ *
+ * @see system_requirements()
+ */
+ protected function setUpRequirementsProblem() {
+ // By default, skip the "recommended PHP version" warning on older test
+ // environments. This allows the installer to be tested consistently on
+ // both recommended PHP versions and older (but still supported) versions.
+ if (version_compare(phpversion(), DRUPAL_RECOMMENDED_PHP) < 0) {
+ $this->continueOnExpectedWarnings(['PHP']);
+ }
+ }
+
+ /**
* Final installer step: Configure site.
*/
protected function setUpSite() {
@@ -218,4 +238,44 @@ abstract class InstallerTestBase extends WebTestBase {
}
}
+ /**
+ * Continues installation when an expected warning is found.
+ *
+ * @param string[] $expected_warnings
+ * A list of warning summaries to expect on the requirements screen (e.g.
+ * 'PHP', 'PHP OPcode caching', etc.). If only the expected warnings
+ * are found, the test will click the "continue anyway" link to go to the
+ * next screen of the installer. If an expected warning is not found, or if
+ * a warning not in the list is present, a fail is raised.
+ */
+ protected function continueOnExpectedWarnings($expected_warnings = []) {
+ // Don't try to continue if there are errors.
+ if (strpos($this->getTextContent(), 'Errors found') !== FALSE) {
+ return;
+ }
+ // Allow only details elements that are directly after the warning header
+ // or each other. There is no guaranteed wrapper we can rely on across
+ // distributions. When there are multiple warnings, the selectors will be:
+ // - h3#warning+details summary
+ // - h3#warning+details+details summary
+ // - etc.
+ // We add one more selector than expected warnings to confirm that there
+ // isn't any other warning before clicking the link.
+ // @todo Make this more reliable in
+ // https://www.drupal.org/project/drupal/issues/2927345.
+ $selectors = [];
+ for ($i = 0; $i <= count($expected_warnings); $i++) {
+ $selectors[] = 'h3#warning' . implode('', array_fill(0, $i + 1, '+details')) . ' summary';
+ }
+ $warning_elements = $this->cssSelect(implode(', ', $selectors));
+
+ // Confirm that there are only the expected warnings.
+ $warnings = [];
+ foreach ($warning_elements as $warning) {
+ $warnings[] = trim((string) $warning);
+ }
+ $this->assertEqual($expected_warnings, $warnings);
+ $this->clickLink('continue anyway');
+ }
+
}
diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php
index 1b68683..85b1e44 100644
--- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php
+++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php
@@ -64,6 +64,27 @@ class DistributionProfileTranslationQueryTest extends InstallerTestBase {
// The unrouted URL assembler does not exist at this point, so we build the
// URL ourselves.
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php' . '?langcode=fr');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpLanguage() {
+ // This step is skipped, because the distribution profile uses a fixed
+ // language.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpProfile() {
+ // This step is skipped, because there is a distribution profile.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpSettings() {
// The language should have been automatically detected, all following
// screens should be translated already.
$elements = $this->xpath('//input[@type="submit"]/@value');
@@ -80,21 +101,8 @@ class DistributionProfileTranslationQueryTest extends InstallerTestBase {
$this->assertRaw($this->info['distribution']['install']['theme']);
// Verify that the "Choose profile" step does not appear.
$this->assertNoText('profile');
- }
- /**
- * {@inheritdoc}
- */
- protected function setUpLanguage() {
- // This step is skipped, because the distribution profile uses a fixed
- // language.
- }
-
- /**
- * {@inheritdoc}
- */
- protected function setUpProfile() {
- // This step is skipped, because there is a distribution profile.
+ parent::setUpSettings();
}
/**
diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php
index 799affe..a4c8091 100644
--- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php
+++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php
@@ -59,7 +59,27 @@ class DistributionProfileTranslationTest extends InstallerTestBase {
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
parent::visitInstaller();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpLanguage() {
+ // This step is skipped, because the distribution profile uses a fixed
+ // language.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpProfile() {
+ // This step is skipped, because there is a distribution profile.
+ }
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUpSettings() {
// The language should have been automatically detected, all following
// screens should be translated already.
$elements = $this->xpath('//input[@type="submit"]/@value');
@@ -76,22 +96,10 @@ class DistributionProfileTranslationTest extends InstallerTestBase {
$this->assertRaw($this->info['distribution']['install']['theme']);
// Verify that the "Choose profile" step does not appear.
$this->assertNoText('profile');
- }
- /**
- * {@inheritdoc}
- */
- protected function setUpLanguage() {
- // This step is skipped, because the distribution profile uses a fixed
- // language.
+ parent::setUpSettings();
}
- /**
- * {@inheritdoc}
- */
- protected function setUpProfile() {
- // This step is skipped, because there is a distribution profile.
- }
/**
* Confirms that the installation succeeded.
diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingInstallationTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingInstallationTest.php
index 3ba045a..442de6c 100644
--- a/core/modules/system/src/Tests/Installer/InstallerExistingInstallationTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerExistingInstallationTest.php
@@ -32,6 +32,7 @@ class InstallerExistingInstallationTest extends InstallerTestBase {
$this->visitInstaller();
$this->setUpLanguage();
$this->setUpProfile();
+ $this->setUpRequirementsProblem();
$this->setUpSettings();
$this->assertRaw('Drupal already installed');
}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index ce48afe..ef6f124 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -157,7 +157,11 @@ function system_requirements($phase) {
}
}
- // Test PHP version and show link to phpinfo() if it's available
+ // Verify the user is running a supported PHP version.
+ // If the site is running a recommended version of PHP, just display it
+ // as an informational message on the status report. This will be overridden
+ // with an error or warning if the site is running older PHP versions for
+ // which Drupal has already or will soon drop support.
$phpversion = $phpversion_label = phpversion();
if (function_exists('phpinfo')) {
if ($phase === 'runtime') {
@@ -169,6 +173,8 @@ function system_requirements($phase) {
];
}
else {
+ // @todo Revisit whether this description makes sense in
+ // https://www.drupal.org/project/drupal/issues/2927318.
$requirements['php'] = [
'title' => t('PHP'),
'value' => $phpversion_label,
@@ -183,11 +189,18 @@ function system_requirements($phase) {
// If PHP is old, it's not safe to continue with the requirements check.
return $requirements;
}
+ // @todo Warn about specific end dates for our PHP 5.5, 5.6, and 7.0 support
+ // once each is set.
+ // @see https://www.drupal.org/project/drupal/issues/2927344
+ if ((version_compare($phpversion, DRUPAL_RECOMMENDED_PHP) < 0) && ($phase === 'install' || $phase === 'runtime')) {
+ $requirements['php']['description'] = t('Your PHP installation is running version %version. Support for this version will be dropped in a future Drupal release. Upgrade to PHP version %recommended or higher to ensure your site continues to receive Drupal updates and remains secure. See <a href="http://php.net/supported-versions.php">PHP\'s version support documentation</a> and the <a href=":php_requirements">Drupal 8 PHP requirements handbook page</a> for more information.', ['%version' => $phpversion, '%recommended' => DRUPAL_RECOMMENDED_PHP, ':php_requirements' => 'https://www.drupal.org/docs/8/system-requirements/php']);
+ $requirements['php']['severity'] = REQUIREMENT_WARNING;
+ }
// Suggest to update to at least 5.5.21 or 5.6.5 for disabling multiple
// statements.
if (($phase === 'install' || \Drupal::database()->driver() === 'mysql') && !SystemRequirements::phpVersionWithPdoDisallowMultipleStatements($phpversion)) {
- $requirements['php'] = [
+ $requirements['php_multiple_statement'] = [
'title' => t('PHP (multiple statement disabling)'),
'value' => $phpversion_label,
'description' => t('PHP versions higher than 5.6.5 or 5.5.21 provide built-in SQL injection protection for mysql databases. It is recommended to update.'),