diff --git a/core/modules/update/src/ProjectSecurityRequirement.php b/core/modules/update/src/ProjectSecurityRequirement.php index cd994e04c97..b14acf5af74 100644 --- a/core/modules/update/src/ProjectSecurityRequirement.php +++ b/core/modules/update/src/ProjectSecurityRequirement.php @@ -2,7 +2,6 @@ namespace Drupal\update; -use Drupal\Core\Render\Markup; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; @@ -138,11 +137,14 @@ final class ProjectSecurityRequirement { if ($security_coverage_message = $this->getVersionEndCoverageMessage()) { $requirement['description'] = $security_coverage_message; if ($this->securityCoverageInfo['additional_minors_coverage'] > 0) { - $requirement['value'] = $this->t('Supported minor version'); + $requirement['value'] = $this->t( + 'Covered until @end_version', + ['@end_version' => $this->securityCoverageInfo['security_coverage_end_version']] + ); $requirement['severity'] = $this->securityCoverageInfo['additional_minors_coverage'] > 1 ? REQUIREMENT_INFO : REQUIREMENT_WARNING; } else { - $requirement['value'] = $this->t('Unsupported minor version'); + $requirement['value'] = $this->t('Coverage has ended'); $requirement['severity'] = REQUIREMENT_ERROR; } } @@ -152,8 +154,8 @@ final class ProjectSecurityRequirement { /** * Gets the message for additional minor version security coverage. * - * @return string|\Drupal\Component\Render\MarkupInterface - * The security coverage message, or an empty string if there is none. + * @return array[] + * A render array containing security coverage message. * * @see \Drupal\update\ProjectSecurityData::getCoverageInfo() */ @@ -161,29 +163,34 @@ final class ProjectSecurityRequirement { if ($this->securityCoverageInfo['additional_minors_coverage'] > 0) { // If the installed minor version will receive security coverage until // newer minor versions are released, inform the user. - $translation_arguments = [ - '@project' => $this->projectTitle, - '@version' => $this->existingMajorMinorVersion, - '@coverage_version' => $this->securityCoverageInfo['security_coverage_end_version'], - ]; - $message = '
' . $this->t('The installed minor version of @project (@version), will stop receiving official security support after the release of @coverage_version.', $translation_arguments) . '
'; - if ($this->securityCoverageInfo['additional_minors_coverage'] === 1) { // If the installed minor version will only receive security coverage // for 1 newer minor core version, encourage the site owner to update // soon. - $message .= '' . $this->t('Update to @next_minor or higher soon to continue receiving security updates.', ['@next_minor' => $this->nextMajorMinorVersion]) - . ' ' . static::getAvailableUpdatesMessage() . '
'; + $message['coverage_message'] = [ + '#markup' => $this->t( + 'Update to @next_minor or higher soon to continue receiving security updates.', + [ + ':update_status_report' => Url::fromRoute('update.status')->toString(), + '@next_minor' => $this->nextMajorMinorVersion, + ] + ), + '#suffix' => ' ', + ]; } } else { // Because the current minor version no longer has security coverage, // advise the site owner to update. - $message = $this->getVersionNoSecurityCoverageMessage(); + $message['coverage_message'] = [ + '#markup' => $this->getVersionNoSecurityCoverageMessage(), + '#suffix' => ' ', + ]; } - $message .= $this->getReleaseCycleLink(); - - return Markup::create($message); + $message['release_cycle_link'] = [ + '#markup' => $this->getReleaseCycleLink(), + ]; + return $message; } /** @@ -212,35 +219,37 @@ final class ProjectSecurityRequirement { // 'Y-m' format. $full_security_coverage_end_date = $this->securityCoverageInfo['security_coverage_end_date'] . '-15'; } - $security_coverage_end_timestamp = \DateTime::createFromFormat('Y-m-d', $full_security_coverage_end_date)->getTimestamp(); - $formatted_end_date = $date_format === 'Y-m-d' - ? $this->securityCoverageInfo['security_coverage_end_date'] - : $date_formatter->format($security_coverage_end_timestamp, 'custom', 'F Y'); + $comparable_request_date = $date_formatter->format($time->getRequestTime(), 'custom', $date_format); if ($this->securityCoverageInfo['security_coverage_end_date'] <= $comparable_request_date) { // Security coverage is over. - $requirement['value'] = $this->t('Unsupported minor version'); + $requirement['value'] = $this->t('Coverage has ended'); $requirement['severity'] = REQUIREMENT_ERROR; - $requirement['description'] = $this->getVersionNoSecurityCoverageMessage(); + $requirement['description']['coverage_message'] = [ + '#markup' => $this->getVersionNoSecurityCoverageMessage(), + '#suffix' => ' ', + ]; } else { - $requirement['value'] = $this->t('Supported minor version'); + $security_coverage_end_timestamp = \DateTime::createFromFormat('Y-m-d', $full_security_coverage_end_date)->getTimestamp(); + $output_date_format = $date_format === 'Y-m-d' ? 'Y-M-d' : 'Y-M'; + $formatted_end_date = $date_formatter + ->format($security_coverage_end_timestamp, 'custom', $output_date_format); + $translation_arguments = ['@date' => $formatted_end_date]; + $requirement['value'] = $this->t('Covered until @date', $translation_arguments); $requirement['severity'] = REQUIREMENT_INFO; - $translation_arguments = [ - '@project' => $this->projectTitle, - '@version' => $this->existingMajorMinorVersion, - '@date' => $formatted_end_date, - ]; - $requirement['description'] = '' . $this->t('The installed minor version of @project (@version), will stop receiving official security support after @date.', $translation_arguments) . '
'; // 'security_coverage_ending_warn_date' will always be in the format // 'Y-m-d'. $request_date = $date_formatter->format($time->getRequestTime(), 'custom', 'Y-m-d'); if (!empty($this->securityCoverageInfo['security_coverage_ending_warn_date']) && $this->securityCoverageInfo['security_coverage_ending_warn_date'] <= $request_date) { - $requirement['description'] .= '' . $this->t('Update to a supported minor version soon to continue receiving security updates.') . '
'; + $requirement['description']['coverage_message'] = [ + '#markup' => $this->t('Update to a supported minor version soon to continue receiving security updates.'), + '#suffix' => ' ', + ]; $requirement['severity'] = REQUIREMENT_WARNING; } } - $requirement['description'] = Markup::create($requirement['description'] . $this->getReleaseCycleLink()); + $requirement['description']['release_cycle_link'] = ['#markup' => $this->getReleaseCycleLink()]; return $requirement; } @@ -251,26 +260,8 @@ final class ProjectSecurityRequirement { * The message for a version with no security coverage. */ private function getVersionNoSecurityCoverageMessage() { - return '' . $this->t( - 'The installed minor version of @project (@version), is no longer supported and will not receive security updates.', - [ - '@project' => $this->projectTitle, - '@version' => $this->existingMajorMinorVersion, - ]) - . '
' - . $this->t('Update to a supported minor as soon as possible to continue receiving security updates.') - . ' ' . static::getAvailableUpdatesMessage() . '
'; - } - - /** - * Gets the message with a link to the available updates page. - * - * @return \Drupal\Core\StringTranslation\TranslatableMarkup - * The message. - */ - private function getAvailableUpdatesMessage() { return $this->t( - 'See the available updates page for more information.', + 'Update to a supported minor as soon as possible to continue receiving security updates.', [':update_status_report' => Url::fromRoute('update.status')->toString()] ); } @@ -282,10 +273,10 @@ final class ProjectSecurityRequirement { * A link to the release cycle page on drupal.org. */ private function getReleaseCycleLink() { - return '' . $this->t( + return $this->t( 'Visit the release cycle overview for more information on supported releases.', [':url' => 'https://www.drupal.org/core/release-cycle-overview'] - ) . '
'; + ); } } diff --git a/core/modules/update/tests/src/Functional/UpdateCoreTest.php b/core/modules/update/tests/src/Functional/UpdateCoreTest.php index abfb354af4f..d6c198f42ec 100644 --- a/core/modules/update/tests/src/Functional/UpdateCoreTest.php +++ b/core/modules/update/tests/src/Functional/UpdateCoreTest.php @@ -425,7 +425,7 @@ class UpdateCoreTest extends UpdateTestBase { // 'Checked', 'Warnings found', or 'Errors found'. $requirements_section_element = $requirements_details->getParent(); $this->assertCount(1, $requirements_section_element->findAll('css', "h3:contains('$requirements_section_heading')")); - $actual_message = $requirements_details->find('css', 'div.description')->getText(); + $actual_message = $requirements_details->find('css', 'div.system-status-report__entry__value')->getText(); $this->assertNotEmpty($actual_message); $this->assertEquals($message, $actual_message); } @@ -450,7 +450,7 @@ class UpdateCoreTest extends UpdateTestBase { */ public function securityCoverageMessageProvider() { $release_coverage_message = 'Visit the release cycle overview for more information on supported releases.'; - $see_available_message = 'See the available updates page for more information.'; + $coverage_ended_message = 'Coverage has ended'; $update_asap_message = 'Update to a supported minor as soon as possible to continue receiving security updates.'; $update_soon_message = 'Update to a supported minor version soon to continue receiving security updates.'; $test_cases = [ @@ -458,35 +458,35 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.0.0', 'fixture' => 'sec.2.0_3.0-rc1', 'requirements_section_heading' => 'Errors found', - 'message' => "The installed minor version of Drupal (8.0), is no longer supported and will not receive security updates.$update_asap_message $see_available_message$release_coverage_message", + 'message' => "$coverage_ended_message $update_asap_message $release_coverage_message", 'mock_date' => '', ], '8.1.0, supported with 3rc' => [ 'installed_version' => '8.1.0', 'fixture' => 'sec.2.0_3.0-rc1', 'requirements_section_heading' => 'Warnings found', - 'message' => "The installed minor version of Drupal (8.1), will stop receiving official security support after the release of 8.3.0.Update to 8.2 or higher soon to continue receiving security updates. $see_available_message$release_coverage_message", + 'message' => "Covered until 8.3.0 Update to 8.2 or higher soon to continue receiving security updates. $release_coverage_message", 'mock_date' => '', ], '8.1.0, supported' => [ 'installed_version' => '8.1.0', 'fixture' => 'sec.2.0', 'requirements_section_heading' => 'Warnings found', - 'message' => "The installed minor version of Drupal (8.1), will stop receiving official security support after the release of 8.3.0.Update to 8.2 or higher soon to continue receiving security updates. $see_available_message$release_coverage_message", + 'message' => "Covered until 8.3.0 Update to 8.2 or higher soon to continue receiving security updates. $release_coverage_message", 'mock_date' => '', ], '8.2.0, supported with 3rc' => [ 'installed_version' => '8.2.0', 'fixture' => 'sec.2.0_3.0-rc1', 'requirements_section_heading' => 'Checked', - 'message' => "The installed minor version of Drupal (8.2), will stop receiving official security support after the release of 8.4.0.$release_coverage_message", + 'message' => "Covered until 8.4.0 $release_coverage_message", 'mock_date' => '', ], '8.2.0, supported' => [ 'installed_version' => '8.2.0', 'fixture' => 'sec.2.0', 'requirements_section_heading' => 'Checked', - 'message' => "The installed minor version of Drupal (8.2), will stop receiving official security support after the release of 8.4.0.$release_coverage_message", + 'message' => "Covered until 8.4.0 $release_coverage_message", 'mock_date' => '', ], // Ensure we don't show messages for pre-release or dev versions. @@ -511,7 +511,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.0.0', 'fixture' => 'sec.2.0_9.0.0', 'requirements_section_heading' => 'Errors found', - 'message' => "The installed minor version of Drupal (8.0), is no longer supported and will not receive security updates.$update_asap_message $see_available_message$release_coverage_message", + 'message' => "$coverage_ended_message $update_asap_message $release_coverage_message", 'mock_date' => '', ], // Ensures the message is correct if the next major version has been @@ -521,7 +521,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.2.0', 'fixture' => 'sec.2.0_9.0.0', 'requirements_section_heading' => 'Warnings found', - 'message' => "The installed minor version of Drupal (8.2), will stop receiving official security support after the release of 8.4.0.Update to 8.3 or higher soon to continue receiving security updates. $see_available_message$release_coverage_message", + 'message' => "Covered until 8.4.0 Update to 8.3 or higher soon to continue receiving security updates. $release_coverage_message", 'mock_date' => '', ], ]; @@ -533,7 +533,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.8.0', 'fixture' => 'sec.9.0', 'requirements_section_heading' => 'Checked', - 'message' => "The installed minor version of Drupal (8.8), will stop receiving official security support after 2020-12-02.$release_coverage_message", + 'message' => "Covered until 2020-Dec-02 $release_coverage_message", 'mock_date' => '2020-06-01', ], // Ensure a warning is displayed if less than six months remain until the @@ -542,7 +542,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.8.0', 'fixture' => 'sec.9.0', 'requirements_section_heading' => 'Warnings found', - 'message' => "The installed minor version of Drupal (8.8), will stop receiving official security support after 2020-12-02.$update_soon_message$release_coverage_message", + 'message' => "Covered until 2020-Dec-02 $update_soon_message $release_coverage_message", 'mock_date' => '2020-06-02', ], ]; @@ -557,7 +557,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.8.0', 'fixture' => 'sec.9.0', 'requirements_section_heading' => 'Errors found', - 'message' => "The installed minor version of Drupal (8.8), is no longer supported and will not receive security updates.$update_asap_message $see_available_message$release_coverage_message", + 'message' => "$coverage_ended_message $update_asap_message $release_coverage_message", 'mock_date' => '2020-12-02', ]; @@ -566,7 +566,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.9.0', 'fixture' => 'sec.9.0', 'requirements_section_heading' => 'Checked', - 'message' => "The installed minor version of Drupal (8.9), will stop receiving official security support after November 2021.$release_coverage_message", + 'message' => "Covered until 2021-Nov $release_coverage_message", 'mock_date' => '2021-01-01', ]; // Ensure that the message does not change, including on the last day of @@ -579,7 +579,7 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '8.9.0', 'fixture' => 'sec.9.0', 'requirements_section_heading' => 'Errors found', - 'message' => "The installed minor version of Drupal (8.9), is no longer supported and will not receive security updates.$update_asap_message $see_available_message$release_coverage_message", + 'message' => "$coverage_ended_message $update_asap_message $release_coverage_message", 'mock_date' => '2021-11-01', ]; @@ -590,14 +590,14 @@ class UpdateCoreTest extends UpdateTestBase { 'installed_version' => '9.9.0', 'fixture' => 'sec.9.9.0', 'requirements_section_heading' => 'Checked', - 'message' => "The installed minor version of Drupal (9.9), will stop receiving official security support after the release of 9.11.0.$release_coverage_message", + 'message' => "Covered until 9.11.0 $release_coverage_message", 'mock_date' => '', ], '9.8.0' => [ 'installed_version' => '9.8.0', 'fixture' => 'sec.9.9.0', 'requirements_section_heading' => 'Warnings found', - 'message' => "The installed minor version of Drupal (9.8), will stop receiving official security support after the release of 9.10.0.Update to 9.9 or higher soon to continue receiving security updates. $see_available_message$release_coverage_message", + 'message' => "Covered until 9.10.0 Update to 9.9 or higher soon to continue receiving security updates. $release_coverage_message", 'mock_date' => '', ], ];