summaryrefslogtreecommitdiffstatshomepage
path: root/core/modules/update/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/update/src')
-rw-r--r--core/modules/update/src/Hook/UpdateHooks.php10
-rw-r--r--core/modules/update/src/Hook/UpdateRequirements.php162
-rw-r--r--core/modules/update/src/ProjectSecurityRequirement.php11
-rw-r--r--core/modules/update/src/UpdateRoot.php10
4 files changed, 180 insertions, 13 deletions
diff --git a/core/modules/update/src/Hook/UpdateHooks.php b/core/modules/update/src/Hook/UpdateHooks.php
index 293882f01246..6577f7f1fc28 100644
--- a/core/modules/update/src/Hook/UpdateHooks.php
+++ b/core/modules/update/src/Hook/UpdateHooks.php
@@ -2,6 +2,7 @@
namespace Drupal\update\Hook;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\update\UpdateManagerInterface;
use Drupal\Core\Url;
@@ -77,8 +78,7 @@ class UpdateHooks {
$verbose = TRUE;
break;
}
- \Drupal::moduleHandler()->loadInclude('update', 'install');
- $status = update_requirements('runtime');
+ $status = \Drupal::moduleHandler()->invoke('update', 'runtime_requirements');
foreach (['core', 'contrib'] as $report_type) {
$type = 'update_' . $report_type;
// hook_requirements() supports render arrays therefore we need to
@@ -89,10 +89,10 @@ class UpdateHooks {
}
if (!empty($verbose)) {
if (isset($status[$type]['severity'])) {
- if ($status[$type]['severity'] == REQUIREMENT_ERROR) {
+ if ($status[$type]['severity'] === RequirementSeverity::Error) {
\Drupal::messenger()->addError($status[$type]['description']);
}
- elseif ($status[$type]['severity'] == REQUIREMENT_WARNING) {
+ elseif ($status[$type]['severity'] === RequirementSeverity::Warning) {
\Drupal::messenger()->addWarning($status[$type]['description']);
}
}
@@ -178,8 +178,6 @@ class UpdateHooks {
\Drupal::moduleHandler()->loadInclude('update', 'inc', 'update.fetch');
_update_cron_notify();
}
- // Clear garbage from disk.
- update_clear_update_disk_cache();
}
/**
diff --git a/core/modules/update/src/Hook/UpdateRequirements.php b/core/modules/update/src/Hook/UpdateRequirements.php
new file mode 100644
index 000000000000..2f51f205b1a0
--- /dev/null
+++ b/core/modules/update/src/Hook/UpdateRequirements.php
@@ -0,0 +1,162 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\update\Hook;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\Link;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Url;
+use Drupal\update\ProjectSecurityData;
+use Drupal\update\ProjectSecurityRequirement;
+use Drupal\update\UpdateFetcherInterface;
+use Drupal\update\UpdateManagerInterface;
+
+/**
+ * Requirements for the update module.
+ */
+class UpdateRequirements {
+
+ use StringTranslationTrait;
+
+ public function __construct(
+ protected readonly ModuleHandlerInterface $moduleHandler,
+ ) {}
+
+ /**
+ * Implements hook_runtime_requirements().
+ *
+ * Describes the status of the site regarding available updates. If
+ * there is no update data, only one record will be returned, indicating that
+ * the status of core can't be determined. If data is available, there will
+ * be two records: one for core, and another for all of contrib (assuming
+ * there are any contributed modules or themes installed on the site). In
+ * addition to the fields expected by hook_requirements ('value', 'severity',
+ * and optionally 'description'), this array will contain a 'reason'
+ * attribute, which is an integer constant to indicate why the given status
+ * is being returned (UPDATE_NOT_SECURE, UPDATE_NOT_CURRENT, or
+ * UPDATE_UNKNOWN). This is used for generating the appropriate email
+ * notification messages during update_cron(), and might be useful for other
+ * modules that invoke update_runtime_requirements() to find out if the site
+ * is up to date or not.
+ *
+ * @see _update_message_text()
+ * @see _update_cron_notify()
+ * @see \Drupal\update\UpdateManagerInterface
+ */
+ #[Hook('runtime_requirements')]
+ public function runtime(): array {
+ $requirements = [];
+ if ($available = update_get_available(FALSE)) {
+ $this->moduleHandler->loadInclude('update', 'inc', 'update.compare');
+ $data = update_calculate_project_data($available);
+ // First, populate the requirements for core:
+ $requirements['update_core'] = $this->requirementCheck($data['drupal'], 'core');
+ if (!empty($available['drupal']['releases'])) {
+ $security_data = ProjectSecurityData::createFromProjectDataAndReleases($data['drupal'], $available['drupal']['releases'])->getCoverageInfo();
+ if ($core_coverage_requirement = ProjectSecurityRequirement::createFromProjectDataAndSecurityCoverageInfo($data['drupal'], $security_data)->getRequirement()) {
+ $requirements['coverage_core'] = $core_coverage_requirement;
+ }
+ }
+
+ // We don't want to check drupal a second time.
+ unset($data['drupal']);
+ if (!empty($data)) {
+ // Now, sort our $data array based on each project's status. The
+ // status constants are numbered in the right order of precedence, so
+ // we just need to make sure the projects are sorted in ascending
+ // order of status, and we can look at the first project we find.
+ uasort($data, '_update_project_status_sort');
+ $first_project = reset($data);
+ $requirements['update_contrib'] = $this->requirementCheck($first_project, 'contrib');
+ }
+ }
+ else {
+ $requirements['update_core']['title'] = $this->t('Drupal core update status');
+ $requirements['update_core']['value'] = $this->t('No update data available');
+ $requirements['update_core']['severity'] = RequirementSeverity::Warning;
+ $requirements['update_core']['reason'] = UpdateFetcherInterface::UNKNOWN;
+ $requirements['update_core']['description'] = _update_no_data();
+ }
+ return $requirements;
+ }
+
+ /**
+ * Fills in the requirements array.
+ *
+ * This is shared for both core and contrib to generate the right elements in
+ * the array for hook_runtime_requirements().
+ *
+ * @param array $project
+ * Array of information about the project we're testing as returned by
+ * update_calculate_project_data().
+ * @param string $type
+ * What kind of project this is ('core' or 'contrib').
+ *
+ * @return array
+ * An array to be included in the nested $requirements array.
+ *
+ * @see hook_requirements()
+ * @see update_requirements()
+ * @see update_calculate_project_data()
+ */
+ protected function requirementCheck($project, $type): array {
+ $requirement = [];
+ if ($type == 'core') {
+ $requirement['title'] = $this->t('Drupal core update status');
+ }
+ else {
+ $requirement['title'] = $this->t('Module and theme update status');
+ }
+ $status = $project['status'];
+ if ($status != UpdateManagerInterface::CURRENT) {
+ $requirement['reason'] = $status;
+ $requirement['severity'] = RequirementSeverity::Error;
+ // When updates are available, append the available updates link to the
+ // message from _update_message_text(), and format the two translated
+ // strings together in a single paragraph.
+ $requirement['description'][] = ['#markup' => _update_message_text($type, $status)];
+ if (!in_array($status, [UpdateFetcherInterface::UNKNOWN, UpdateFetcherInterface::NOT_CHECKED, UpdateFetcherInterface::NOT_FETCHED, UpdateFetcherInterface::FETCH_PENDING])) {
+ $requirement['description'][] = ['#prefix' => ' ', '#markup' => $this->t('See the <a href=":available_updates">available updates</a> page for more information.', [':available_updates' => Url::fromRoute('update.status')->toString()])];
+ }
+ }
+ switch ($status) {
+ case UpdateManagerInterface::NOT_SECURE:
+ $requirement_label = $this->t('Not secure!');
+ break;
+
+ case UpdateManagerInterface::REVOKED:
+ $requirement_label = $this->t('Revoked!');
+ break;
+
+ case UpdateManagerInterface::NOT_SUPPORTED:
+ $requirement_label = $this->t('Unsupported release');
+ break;
+
+ case UpdateManagerInterface::NOT_CURRENT:
+ $requirement_label = $this->t('Out of date');
+ $requirement['severity'] = RequirementSeverity::Warning;
+ break;
+
+ case UpdateFetcherInterface::UNKNOWN:
+ case UpdateFetcherInterface::NOT_CHECKED:
+ case UpdateFetcherInterface::NOT_FETCHED:
+ case UpdateFetcherInterface::FETCH_PENDING:
+ $requirement_label = $project['reason'] ?? $this->t('Can not determine status');
+ $requirement['severity'] = RequirementSeverity::Warning;
+ break;
+
+ default:
+ $requirement_label = $this->t('Up to date');
+ }
+ if ($status != UpdateManagerInterface::CURRENT && $type == 'core' && isset($project['recommended'])) {
+ $requirement_label .= ' ' . $this->t('(version @version available)', ['@version' => $project['recommended']]);
+ }
+ $requirement['value'] = Link::fromTextAndUrl($requirement_label, Url::fromRoute('update.status'))->toString();
+ return $requirement;
+ }
+
+}
diff --git a/core/modules/update/src/ProjectSecurityRequirement.php b/core/modules/update/src/ProjectSecurityRequirement.php
index cc6fed789fea..331c65537c85 100644
--- a/core/modules/update/src/ProjectSecurityRequirement.php
+++ b/core/modules/update/src/ProjectSecurityRequirement.php
@@ -2,6 +2,7 @@
namespace Drupal\update;
+use Drupal\Core\Extension\Requirement\RequirementSeverity;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
@@ -141,11 +142,11 @@ final class ProjectSecurityRequirement {
'Covered until @end_version',
['@end_version' => $this->securityCoverageInfo['security_coverage_end_version']]
);
- $requirement['severity'] = $this->securityCoverageInfo['additional_minors_coverage'] > 1 ? REQUIREMENT_INFO : REQUIREMENT_WARNING;
+ $requirement['severity'] = $this->securityCoverageInfo['additional_minors_coverage'] > 1 ? RequirementSeverity::Info : RequirementSeverity::Warning;
}
else {
$requirement['value'] = $this->t('Coverage has ended');
- $requirement['severity'] = REQUIREMENT_ERROR;
+ $requirement['severity'] = RequirementSeverity::Error;
}
}
return $requirement;
@@ -224,7 +225,7 @@ final class ProjectSecurityRequirement {
if ($this->securityCoverageInfo['security_coverage_end_date'] <= $comparable_request_date) {
// Security coverage is over.
$requirement['value'] = $this->t('Coverage has ended');
- $requirement['severity'] = REQUIREMENT_ERROR;
+ $requirement['severity'] = RequirementSeverity::Error;
$requirement['description']['coverage_message'] = [
'#markup' => $this->getVersionNoSecurityCoverageMessage(),
'#suffix' => ' ',
@@ -237,7 +238,7 @@ final class ProjectSecurityRequirement {
->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;
+ $requirement['severity'] = RequirementSeverity::Info;
// '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');
@@ -246,7 +247,7 @@ final class ProjectSecurityRequirement {
'#markup' => $this->t('Update to a supported version soon to continue receiving security updates.'),
'#suffix' => ' ',
];
- $requirement['severity'] = REQUIREMENT_WARNING;
+ $requirement['severity'] = RequirementSeverity::Warning;
}
}
$requirement['description']['release_cycle_link'] = ['#markup' => $this->getReleaseCycleLink()];
diff --git a/core/modules/update/src/UpdateRoot.php b/core/modules/update/src/UpdateRoot.php
index a2f1619d6ea6..604e9ff0f529 100644
--- a/core/modules/update/src/UpdateRoot.php
+++ b/core/modules/update/src/UpdateRoot.php
@@ -6,7 +6,12 @@ use Drupal\Core\DrupalKernelInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
- * Gets the root path used by the Update Manager to install or update projects.
+ * Gets the root path used by the legacy Update Manager.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no
+ * replacement. Use composer to manage the code for your site.
+ *
+ * @see https://www.drupal.org/node/3522119
*/
class UpdateRoot {
@@ -32,7 +37,7 @@ class UpdateRoot {
protected $updateRoot;
/**
- * Constructs an UpdateRootFactory instance.
+ * Constructs an UpdateRoot instance.
*
* @param \Drupal\Core\DrupalKernelInterface $drupal_kernel
* The Drupal kernel.
@@ -40,6 +45,7 @@ class UpdateRoot {
* The request stack.
*/
public function __construct(DrupalKernelInterface $drupal_kernel, RequestStack $request_stack) {
+ @trigger_error(__CLASS__ . ' is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no replacement. Use composer to manage the code for your site. See https://www.drupal.org/node/3522119', E_USER_DEPRECATED);
$this->drupalKernel = $drupal_kernel;
$this->requestStack = $request_stack;
}