Skip to content
Snippets Groups Projects
automatic_updates.module 6.08 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
     * @file
     * Contains automatic_updates.module..
     */
    
    
    use Drupal\automatic_updates\ReadinessChecker\ReadinessCheckerManagerInterface;
    
    /**
     * Implements hook_page_top().
     */
    function automatic_updates_page_top(array &$page_top) {
      /** @var \Drupal\Core\Routing\AdminContext $admin_context */
      $admin_context = \Drupal::service('router.admin_context');
      $route_match = \Drupal::routeMatch();
      if ($admin_context->isAdminRoute($route_match->getRouteObject()) && \Drupal::currentUser()->hasPermission('administer site configuration')) {
        $disabled_routes = [
          'update.theme_update',
          'system.theme_install',
          'update.module_update',
          'update.module_install',
          'update.status',
          'update.report_update',
          'update.report_install',
          'update.settings',
          'system.status',
          'update.confirmation_page',
        ];
        // These routes don't need additional nagging.
        if (in_array(\Drupal::routeMatch()->getRouteName(), $disabled_routes, TRUE)) {
    
        }
        /** @var \Drupal\automatic_updates\Services\AutomaticUpdatesPsaInterface $psa */
        $psa = \Drupal::service('automatic_updates.psa');
    
        $messages = $psa->getPublicServiceMessages();
        if ($messages) {
    
          \Drupal::messenger()->addError(t('Public service announcements:'));
    
          foreach ($messages as $message) {
            \Drupal::messenger()->addError($message);
          }
    
        $last_check_timestamp = \Drupal::service('automatic_updates.readiness_checker')->timestamp();
        if (\Drupal::time()->getRequestTime() > $last_check_timestamp + ReadinessCheckerManagerInterface::LAST_CHECKED_WARNING) {
          \Drupal::messenger()->addError(t('Your site has not recently run an update readiness check.'));
        }
        /** @var \Drupal\automatic_updates\ReadinessChecker\ReadinessCheckerManagerInterface $checker */
        $checker = \Drupal::service('automatic_updates.readiness_checker');
    
        $results = $checker->getResults(ReadinessCheckerManagerInterface::ERROR);
    
        if ($results) {
          \Drupal::messenger()->addError(t('Your site is currently failing readiness checks for automatic updates. It cannot be <a href="@readiness_checks">automatically updated</a> until further action is performed:', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks']));
          foreach ($results as $message) {
            \Drupal::messenger()->addError($message);
          }
        }
        $results = $checker->getResults('warning');
        if ($results) {
    
          \Drupal::messenger()->addWarning(t('Your site does not pass some readiness checks for automatic updates. Depending on the nature of the failures, it might effect the eligibility for <a href="@readiness_checks">automatic updates</a>.', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks']));
    
          foreach ($results as $message) {
            \Drupal::messenger()->addWarning($message);
          }
        }
      }
    }
    
    /**
     * Implements hook_cron().
     */
    function automatic_updates_cron() {
    
      $state = \Drupal::state();
      $request_time = \Drupal::time()->getRequestTime();
      $last_check = $state->get('automatic_updates.last_check', 0);
      // Only allow cron to run once every hour.
      if (($request_time - $last_check) < 3600) {
        return;
      }
    
      // In-place updates won't function for dev releases of Drupal core.
    
      $dev_core = strpos(\Drupal::VERSION, '-dev') !== FALSE;
    
      /** @var \Drupal\Core\Config\ImmutableConfig $config */
      $config = \Drupal::config('automatic_updates.settings');
    
      if (!$dev_core && $config->get('enable_cron_updates')) {
    
        \Drupal::service('update.manager')->refreshUpdateData();
    
        \Drupal::service('update.processor')->fetchData();
    
        $available = update_get_available(TRUE);
    
        $projects = update_calculate_project_data($available);
        $not_recommended_version = $projects['drupal']['status'] !== UpdateManagerInterface::CURRENT;
        $security_update = in_array($projects['drupal']['status'], [UpdateManagerInterface::NOT_SECURE, UpdateManagerInterface::REVOKED], TRUE);
    
        $recommended_release = isset($projects['drupal']['releases'][$projects['drupal']['recommended']]) ? $projects['drupal']['releases'][$projects['drupal']['recommended']] : NULL;
        $major_upgrade = isset($recommended_release['version_major']) ? $recommended_release['version_major'] !== $projects['drupal']['existing_major'] : TRUE;
    
        // Don't automatically update major version bumps or a dev version of core.
    
        if (!$major_upgrade && $config->get('enable_cron_security_updates')) {
    
          if ($not_recommended_version && $security_update) {
    
            /** @var \Drupal\automatic_updates\Services\UpdateInterface $updater */
            $updater = \Drupal::service('automatic_updates.update');
    
            $updater->update('drupal', 'core', \Drupal::VERSION, $recommended_release['version']);
    
        elseif (!$major_upgrade && $not_recommended_version) {
    
          /** @var \Drupal\automatic_updates\Services\UpdateInterface $updater */
          $updater = \Drupal::service('automatic_updates.update');
    
          $updater->update('drupal', 'core', \Drupal::VERSION, $recommended_release['version']);
    
    
      /** @var \Drupal\automatic_updates\Services\NotifyInterface $notify */
      $notify = \Drupal::service('automatic_updates.psa_notify');
      $notify->send();
      /** @var \Drupal\automatic_updates\ReadinessChecker\ReadinessCheckerManagerInterface $checker */
      $checker = \Drupal::service('automatic_updates.readiness_checker');
      foreach ($checker->getCategories() as $category) {
        $checker->run($category);
      }
    
      $state->set('automatic_updates.last_check', \Drupal::time()->getCurrentTime());
    
    
    /**
     * Implements hook_theme().
     */
    function automatic_updates_theme(array $existing, $type, $theme, $path) {
      return [
        'automatic_updates_psa_notify' => [
          'variables' => [
            'messages' => [],
          ],
        ],
      ];
    }
    
    /**
     * Implements hook_mail().
     */
    function automatic_updates_mail($key, &$message, $params) {
      /** @var \Drupal\Core\Render\RendererInterface $renderer */
      $renderer = \Drupal::service('renderer');
    
      $message['subject'] = $params['subject'];
      $message['body'][] = $renderer->render($params['body']);
    }