diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 499f552..68d8cb8 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -20,7 +20,11 @@
/**
* Minimum supported version of PHP.
*
- * Drupal cannot be installed on versions of PHP older than this version.
+ * Updates cannot be run on versions of PHP older than this version.
+ *
+ * The installer exits early on versions of PHP older than this version.
+ *
+ * @see install.php
*
* @todo Move this to an appropriate autoloadable class. See
* https://www.drupal.org/project/drupal/issues/2908079
@@ -28,6 +32,14 @@
const DRUPAL_MINIMUM_PHP = '5.5.9';
/**
+ * Drupal cannot be installed on versions of PHP older than this version.
+ *
+ * @todo Move this to an appropriate autoloadable class. See
+ * https://www.drupal.org/project/drupal/issues/2908079
+ */
+const DRUPAL_MINIMUM_INSTALL_PHP = '7.0.8';
+
+/**
* Minimum recommended version of PHP.
*
* Sites installing Drupal on PHP versions lower than this will see a warning
diff --git a/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php b/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
index 3e39f74..ba5afb9 100644
--- a/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
+++ b/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
@@ -4,6 +4,7 @@
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Adds and configures languages to check field schema definition.
@@ -12,6 +13,8 @@
*/
class LocaleTranslatedSchemaDefinitionTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* Modules to enable.
*
@@ -83,6 +86,8 @@ public function testTranslatedUpdate() {
// markup and a link instead of specific text because text may be
// translated.
$this->drupalGet($update_url . '/selection', ['external' => TRUE]);
+ $this->updateRequirementsProblem();
+ $this->drupalGet($update_url . '/selection', ['external' => TRUE]);
$this->assertRaw('messages--status', 'No pending updates.');
$this->assertNoLinkByHref('fr/update.php/run', 'No link to run updates.');
}
diff --git a/core/modules/simpletest/src/InstallerTestBase.php b/core/modules/simpletest/src/InstallerTestBase.php
index 369c3ab..0f4af3a 100644
--- a/core/modules/simpletest/src/InstallerTestBase.php
+++ b/core/modules/simpletest/src/InstallerTestBase.php
@@ -8,6 +8,7 @@
use Drupal\Core\Language\Language;
use Drupal\Core\Session\UserSession;
use Drupal\Core\Site\Settings;
+use Drupal\Tests\RequirementsPageTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
@@ -22,6 +23,8 @@
*/
abstract class InstallerTestBase extends WebTestBase {
+ use RequirementsPageTrait;
+
/**
* Custom settings.php values to write for a test run.
*
@@ -213,12 +216,7 @@ protected function setUpSettings() {
* @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(), '7.0') < 0) {
- $this->continueOnExpectedWarnings(['PHP']);
- }
+ // Do nothing.
}
/**
@@ -244,44 +242,4 @@ protected function refreshVariables() {
}
}
- /**
- * 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/system.install b/core/modules/system/system.install
index 960bb7d..d4f3e87 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -186,26 +186,34 @@ function system_requirements($phase) {
];
}
- if (version_compare($phpversion, DRUPAL_MINIMUM_PHP) < 0) {
- $requirements['php']['description'] = t('Your PHP installation is too old. Drupal requires at least PHP %version.', ['%version' => DRUPAL_MINIMUM_PHP]);
+ if (version_compare($phpversion, DRUPAL_MINIMUM_INSTALL_PHP) < 0) {
+ $requirements['php']['description'] = t('Your PHP installation is too old. Drupal requires at least PHP %version. It is recommended to upgrade to PHP version %recommended or higher for the best ongoing support. See PHP\'s version support documentation and the Drupal 8 PHP requirements handbook page for more information.',
+ [
+ '%version' => DRUPAL_MINIMUM_INSTALL_PHP,
+ '%recommended' => DRUPAL_RECOMMENDED_PHP,
+ ':php_requirements' => 'https://www.drupal.org/docs/8/system-requirements/php',
+ ]
+ );
$requirements['php']['severity'] = REQUIREMENT_ERROR;
+
// If PHP is old, it's not safe to continue with the requirements check.
- return $requirements;
- }
- if ((version_compare($phpversion, DRUPAL_RECOMMENDED_PHP) < 0) && ($phase === 'install' || $phase === 'runtime')) {
- // Warn if still on PHP 5. If at least PHP 7.0, relax from "warning" to
- // "info", and show it at runtime only, to not scare users while installing.
- if (version_compare($phpversion, '7.0') < 0) {
- $requirements['php']['description'] = t('Drupal will drop support for this version on March 6, 2019. Upgrade to PHP version %recommended or higher to ensure your site can receive updates and remain secure. See PHP\'s version support documentation and the Drupal 8 PHP requirements handbook page for more information.', ['%recommended' => DRUPAL_RECOMMENDED_PHP, ':php_requirements' => 'https://www.drupal.org/docs/8/system-requirements/php']);
+ if (version_compare($phpversion, DRUPAL_MINIMUM_PHP) < 0) {
+ return $requirements;
+ }
+ // Only show a warning during updates, so sites running on an older version
+ // of PHP are still able to run them.
+ elseif ($phase === 'update') {
$requirements['php']['severity'] = REQUIREMENT_WARNING;
}
- else {
- if ($phase === 'runtime') {
- $requirements['php']['description'] = t('It is recommended to upgrade to PHP version %recommended or higher for the best ongoing support. See PHP\'s version support documentation and the Drupal 8 PHP requirements handbook page for more information.', ['%recommended' => DRUPAL_RECOMMENDED_PHP, ':php_requirements' => 'https://www.drupal.org/docs/8/system-requirements/php']);
- $requirements['php']['severity'] = REQUIREMENT_INFO;
- }
+ // Allow test installations of Drupal on older PHP versions.
+ elseif ($phase === 'install' && drupal_valid_test_ua()) {
+ $requirements['php']['severity'] = REQUIREMENT_INFO;
}
}
+ elseif ($phase === 'runtime' && version_compare($phpversion, DRUPAL_RECOMMENDED_PHP) < 0) {
+ $requirements['php']['description'] = t('It is recommended to upgrade to PHP version %recommended or higher for the best ongoing support. See PHP\'s version support documentation and the Drupal 8 PHP requirements handbook page for more information.', ['%recommended' => DRUPAL_RECOMMENDED_PHP, ':php_requirements' => 'https://www.drupal.org/docs/8/system-requirements/php']);
+ $requirements['php']['severity'] = REQUIREMENT_INFO;
+ }
// Suggest to update to at least 5.5.21 or 5.6.5 for disabling multiple
// statements.
diff --git a/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php b/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php
index 55f3a04..5fbc1ee 100644
--- a/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php
+++ b/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php
@@ -4,6 +4,7 @@
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Provides methods to conditionally enable db update functions and apply
@@ -14,6 +15,7 @@
trait DbUpdatesTrait {
use StringTranslationTrait;
+ use RequirementsPageTrait;
/**
* Enables db updates until the specified index.
@@ -34,6 +36,7 @@ protected function enableUpdates($module, $group, $index) {
*/
protected function applyUpdates() {
$this->drupalGet(Url::fromRoute('system.db_update'));
+ $this->updateRequirementsProblem();
$this->clickLink($this->t('Continue'));
$this->clickLink($this->t('Apply pending updates'));
$this->checkForMetaRefresh();
diff --git a/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php b/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php
index 85d041e..44fdf81 100644
--- a/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php
+++ b/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php
@@ -3,6 +3,7 @@
namespace Drupal\Tests\system\Functional\Update;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Tests that a module implementing hook_update_8000() causes an error to be
@@ -12,6 +13,8 @@
*/
class InvalidUpdateHookTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* Modules to enable.
*
@@ -45,6 +48,7 @@ public function testInvalidUpdateHook() {
// Confirm that a module with hook_update_8000() cannot be updated.
$this->drupalLogin($this->updateUser);
$this->drupalGet($this->updateUrl);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertText(t('Some of the pending updates cannot be applied because their dependencies were not met.'));
}
diff --git a/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php
index fd9e011..3e2c46a 100644
--- a/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php
+++ b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php
@@ -78,6 +78,8 @@ public function testPostUpdate() {
}
$this->drupalGet('update.php/selection');
+ $this->updateRequirementsProblem();
+ $this->drupalGet('update.php/selection');
$this->assertText('No pending updates.');
}
diff --git a/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php b/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php
index e35d52b..aa28be0 100644
--- a/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php
+++ b/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php
@@ -5,6 +5,7 @@
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Tests that update hooks are properly run.
@@ -13,6 +14,8 @@
*/
class UpdateSchemaTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* {@inheritdoc}
*/
@@ -56,6 +59,7 @@ public function testUpdateHooks() {
$this->drupalLogin($this->user);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertRaw('Schema version 8001.');
// Run the update hooks.
diff --git a/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
index da215d4..162cbf4 100644
--- a/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
+++ b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
@@ -5,6 +5,7 @@
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Tests the update script access and functionality.
@@ -13,6 +14,8 @@
*/
class UpdateScriptTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* Modules to enable.
*
@@ -99,6 +102,7 @@ public function testRequirements() {
// If there are no requirements warnings or errors, we expect to be able to
// go through the update process uninterrupted.
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertText(t('No pending updates.'), 'End of update process was reached.');
// Confirm that all caches were cleared.
@@ -110,6 +114,7 @@ public function testRequirements() {
// First, run this test with pending updates to make sure they can be run
// successfully.
+ $this->drupalLogin($this->updateUser);
$update_script_test_config->set('requirement_type', REQUIREMENT_WARNING)->save();
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
@@ -177,6 +182,7 @@ public function testNoUpdateFunctionality() {
// Click through update.php with 'administer software updates' permission.
$this->drupalLogin($this->updateUser);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertText(t('No pending updates.'));
$this->assertNoLink('Administration pages');
@@ -188,6 +194,7 @@ public function testNoUpdateFunctionality() {
$admin_user = $this->drupalCreateUser(['administer software updates', 'access administration pages']);
$this->drupalLogin($admin_user);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertText(t('No pending updates.'));
$this->assertLink('Administration pages');
@@ -220,6 +227,7 @@ public function testSuccessfulUpdateFunctionality() {
$admin_user = $this->drupalCreateUser(['administer software updates', 'access administration pages', 'access site reports', 'access site in maintenance mode']);
$this->drupalLogin($admin_user);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->clickLink(t('Apply pending updates'));
$this->checkForMetaRefresh();
@@ -287,6 +295,7 @@ public function testSuccessfulMultilingualUpdateFunctionality() {
// Click through update.php with 'access administration pages' and
// 'access site reports' permissions.
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->clickLink(t('Apply pending updates'));
$this->checkForMetaRefresh();
@@ -319,6 +328,7 @@ protected function runUpdates($maintenance_mode) {
$this->assertNoText('Operating in maintenance mode.');
}
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->clickLink(t('Apply pending updates'));
$this->checkForMetaRefresh();
diff --git a/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php b/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php
index 4f536ea..7d3a5ef 100644
--- a/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php
+++ b/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php
@@ -3,6 +3,7 @@
namespace Drupal\Tests\system\Functional\Update;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
/**
* Tests that the minimum schema version is correct even if only 7.x update
@@ -12,6 +13,8 @@
*/
class UpdatesWith7xTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* Modules to enable.
*
@@ -48,6 +51,7 @@ public function testWith7x() {
// Click through update.php with 'administer software updates' permission.
$this->drupalLogin($this->updateUser);
$this->drupalGet($this->updateUrl, ['external' => TRUE]);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->assertText(t('Some of the pending updates cannot be applied because their dependencies were not met.'));
}
diff --git a/core/profiles/minimal/tests/src/Functional/MinimalTest.php b/core/profiles/minimal/tests/src/Functional/MinimalTest.php
index 568918a..d743fee 100644
--- a/core/profiles/minimal/tests/src/Functional/MinimalTest.php
+++ b/core/profiles/minimal/tests/src/Functional/MinimalTest.php
@@ -3,6 +3,7 @@
namespace Drupal\Tests\minimal\Functional;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
use Drupal\user\UserInterface;
/**
@@ -12,6 +13,8 @@
*/
class MinimalTest extends BrowserTestBase {
+ use RequirementsPageTrait;
+
protected $profile = 'minimal';
/**
@@ -34,6 +37,8 @@ public function testMinimal() {
// Ensure that there are no pending updates after installation.
$this->drupalLogin($this->rootUser);
$this->drupalGet('update.php/selection');
+ $this->updateRequirementsProblem();
+ $this->drupalGet('update.php/selection');
$this->assertText('No pending updates.');
// Ensure that there are no pending entity updates after installation.
diff --git a/core/profiles/standard/tests/src/Functional/StandardTest.php b/core/profiles/standard/tests/src/Functional/StandardTest.php
index 79584b4..f62e183 100644
--- a/core/profiles/standard/tests/src/Functional/StandardTest.php
+++ b/core/profiles/standard/tests/src/Functional/StandardTest.php
@@ -10,6 +10,7 @@
use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
use Drupal\user\Entity\Role;
/**
@@ -20,6 +21,7 @@
class StandardTest extends BrowserTestBase {
use SchemaCheckTestTrait;
+ use RequirementsPageTrait;
protected $profile = 'standard';
@@ -155,6 +157,8 @@ public function testStandard() {
// Ensure that there are no pending updates after installation.
$this->drupalLogin($this->rootUser);
$this->drupalGet('update.php/selection');
+ $this->updateRequirementsProblem();
+ $this->drupalGet('update.php/selection');
$this->assertText('No pending updates.');
// Ensure that there are no pending entity updates after installation.
diff --git a/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php b/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php
index 9810f34..a66bd57 100644
--- a/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php
+++ b/core/tests/Drupal/FunctionalTests/Installer/InstallerTestBase.php
@@ -8,6 +8,7 @@
use Drupal\Core\Site\Settings;
use Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware;
use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
use GuzzleHttp\HandlerStack;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
@@ -19,6 +20,8 @@
*/
abstract class InstallerTestBase extends BrowserTestBase {
+ use RequirementsPageTrait;
+
/**
* Custom settings.php values to write for a test run.
*
@@ -244,12 +247,7 @@ protected function setUpSettings() {
* @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(), '7.0') < 0) {
- $this->continueOnExpectedWarnings(['PHP']);
- }
+ // Do nothing.
}
/**
@@ -275,45 +273,4 @@ protected function refreshVariables() {
}
}
- /**
- * 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($warning->getText());
- }
- $this->assertEquals($expected_warnings, $warnings);
- $this->clickLink('continue anyway');
- $this->checkForMetaRefresh();
- }
-
}
diff --git a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
index a127ab4..af27c7d 100644
--- a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
@@ -10,6 +10,7 @@
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Language\Language;
use Drupal\Core\Url;
+use Drupal\Tests\RequirementsPageTrait;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
@@ -42,6 +43,7 @@
abstract class UpdatePathTestBase extends BrowserTestBase {
use SchemaCheckTestTrait;
+ use RequirementsPageTrait;
/**
* Modules to enable after the database is loaded.
@@ -295,6 +297,7 @@ protected function runUpdates() {
]);
$this->drupalGet($this->updateUrl);
+ $this->updateRequirementsProblem();
$this->clickLink(t('Continue'));
$this->doSelectionTest();
diff --git a/core/tests/Drupal/Tests/Core/Command/QuickStartTest.php b/core/tests/Drupal/Tests/Core/Command/QuickStartTest.php
index 5622aa2..fe2788b 100644
--- a/core/tests/Drupal/Tests/Core/Command/QuickStartTest.php
+++ b/core/tests/Drupal/Tests/Core/Command/QuickStartTest.php
@@ -58,6 +58,7 @@ public function setUp() {
}
// Get a lock and a valid site path.
$this->testDb = new TestDatabase();
+ include $this->root . '/core/includes/bootstrap.inc';
}
/**
@@ -83,6 +84,10 @@ public function tearDown() {
* Tests the quick-start command.
*/
public function testQuickStartCommand() {
+ if (version_compare(phpversion(), DRUPAL_MINIMUM_INSTALL_PHP) < 0) {
+ $this->markTestSkipped();
+ }
+
// Install a site using the standard profile to ensure the one time login
// link generation works.
@@ -117,7 +122,6 @@ public function testQuickStartCommand() {
$this->assertContains("127.0.0.1:$port/user/reset/1/", $process->getOutput());
// Generate a cookie so we can make a request against the installed site.
- include $this->root . '/core/includes/bootstrap.inc';
define('DRUPAL_TEST_IN_CHILD_SITE', FALSE);
chmod($this->testDb->getTestSitePath(), 0755);
$cookieJar = CookieJar::fromArray([
@@ -133,9 +137,47 @@ public function testQuickStartCommand() {
}
/**
+ * Tests that the installer throws a requirement error on older PHP versions.
+ */
+ public function testPhpRequirement() {
+ if (version_compare(phpversion(), DRUPAL_MINIMUM_INSTALL_PHP) >= 0) {
+ $this->markTestSkipped();
+ }
+
+ $install_command = [
+ $this->php,
+ 'core/scripts/drupal',
+ 'quick-start',
+ 'standard',
+ "--site-name='Test site {$this->testDb->getDatabasePrefix()}'",
+ '--suppress-login',
+ ];
+ $process = new Process($install_command, NULL, ['DRUPAL_DEV_SITE_PATH' => $this->testDb->getTestSitePath()]);
+ $process->inheritEnvironmentVariables();
+ $process->setTimeout(500);
+ $process->start();
+ while ($process->isRunning()) {
+ // Wait for more output.
+ sleep(1);
+ }
+
+ $error_output = $process->getErrorOutput();
+ $this->assertContains('Your PHP installation is too old.', $error_output);
+ $this->assertContains('Drupal requires at least PHP', $error_output);
+ $this->assertContains(DRUPAL_MINIMUM_INSTALL_PHP, $error_output);
+
+ // Stop the web server.
+ $process->stop();
+ }
+
+ /**
* Tests the quick-start commands.
*/
public function testQuickStartInstallAndServerCommands() {
+ if (version_compare(phpversion(), DRUPAL_MINIMUM_INSTALL_PHP) < 0) {
+ $this->markTestSkipped();
+ }
+
// Install a site.
$install_command = [
$this->php,
@@ -180,7 +222,6 @@ public function testQuickStartInstallAndServerCommands() {
sleep(2);
// Generate a cookie so we can make a request against the installed site.
- include $this->root . '/core/includes/bootstrap.inc';
define('DRUPAL_TEST_IN_CHILD_SITE', FALSE);
chmod($this->testDb->getTestSitePath(), 0755);
$cookieJar = CookieJar::fromArray([
diff --git a/core/tests/Drupal/Tests/RequirementsPageTrait.php b/core/tests/Drupal/Tests/RequirementsPageTrait.php
new file mode 100644
index 0000000..82e87ca
--- /dev/null
+++ b/core/tests/Drupal/Tests/RequirementsPageTrait.php
@@ -0,0 +1,75 @@
+assertNoText('Errors found');
+ $this->assertWarningSummaries(['PHP']);
+ $this->clickLink('try again');
+ $this->checkForMetaRefresh();
+ }
+ }
+
+ /**
+ * Continues installation when the expected warnings are 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 = []) {
+ $this->assertNoText('Errors found');
+ $this->assertWarningSummaries($expected_warnings);
+ $this->clickLink('continue anyway');
+ $this->checkForMetaRefresh();
+ }
+
+ /**
+ * Assert the given warning summaries are present on the page.
+ *
+ * If an expected warning is not found, or if a warning not in the list is
+ * present, a fail is raised.
+ *
+ * @param string[] $warning_summaries
+ * A list of warning summaries to expect on the requirements screen (e.g.
+ * 'PHP', 'PHP OPcode caching', etc.).
+ */
+ protected function assertWarningSummaries(array $warning_summaries) {
+ // 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($warning_summaries); $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($warning->getText());
+ }
+ $this->assertEquals($warning_summaries, $warnings);
+ }
+
+}