class UpdateRequirements

Requirements for the update module.

Hierarchy

Expanded class hierarchy of UpdateRequirements

File

core/modules/update/src/Hook/UpdateRequirements.php, line 20

Namespace

Drupal\update\Hook
View source
class UpdateRequirements {
    use StringTranslationTrait;
    public function __construct(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
     */
    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'] = REQUIREMENT_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'] = REQUIREMENT_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'] = REQUIREMENT_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'] = REQUIREMENT_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;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overrides
StringTranslationTrait::$stringTranslation protected property The string translation service. 3
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language. 1
UpdateRequirements::requirementCheck protected function Fills in the requirements array.
UpdateRequirements::runtime public function Implements hook_runtime_requirements().
UpdateRequirements::__construct public function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.