<?php /** * @file * Contains hook implementations for Automatic Updates. */ use Drupal\automatic_updates\CronUpdater; use Drupal\automatic_updates\UpdateRecommender; use Drupal\automatic_updates\Validation\AdminReadinessMessages; use Drupal\Core\Extension\ExtensionVersion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\update\ProjectSecurityData; /** * Implements hook_page_top(). */ function automatic_updates_page_top() { /** @var \Drupal\automatic_updates\Validation\AdminReadinessMessages $readiness_messages */ $readiness_messages = \Drupal::classResolver(AdminReadinessMessages::class); $readiness_messages->displayAdminPageMessages(); } /** * Implements hook_cron(). */ function automatic_updates_cron() { /** @var \Drupal\automatic_updates\CronUpdater $cron_updater */ $cron_updater = \Drupal::classResolver(CronUpdater::class); $cron_updater->handleCron(); /** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $checker_manager */ $checker_manager = \Drupal::service('automatic_updates.readiness_validation_manager'); $last_results = $checker_manager->getResults(); $last_run_time = $checker_manager->getLastRunTime(); // Do not run readiness checks more than once an hour unless there are no // results available. if ($last_results === NULL || !$last_run_time || \Drupal::time()->getRequestTime() - $last_run_time > 3600) { $checker_manager->run(); } } /** * Implements hook_modules_installed(). */ function automatic_updates_modules_installed() { // Run the readiness checkers if needed when any modules are installed in // case they provide readiness checker services. /** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $checker_manager */ $checker_manager = \Drupal::service('automatic_updates.readiness_validation_manager'); $checker_manager->runIfNoStoredResults(); } /** * Implements hook_modules_uninstalled(). */ function automatic_updates_modules_uninstalled() { // Run the readiness checkers if needed when any modules are uninstalled in // case they provided readiness checker services. /** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $checker_manager */ $checker_manager = \Drupal::service('automatic_updates.readiness_validation_manager'); $checker_manager->runIfNoStoredResults(); } /** * Implements hook_form_FORM_ID_alter() for 'update_manager_update_form'. */ function automatic_updates_form_update_manager_update_form_alter(&$form, FormStateInterface $form_state, $form_id) { // Remove current message that core updates are not supported with a link to // use this modules form. if (isset($form['manual_updates']['#rows']['drupal']['data']['title'])) { $current_route = \Drupal::routeMatch()->getRouteName(); if ($current_route === 'update.module_update') { $redirect_route = 'automatic_updates.module_update'; } elseif ($current_route === 'update.report_update') { $redirect_route = 'automatic_updates.report_update'; } if (!empty($redirect_route)) { $core_updates_message = t( '<h2>Core updates required</h2>Drupal core updates are supported by the enabled <a href="@url">Automatic Updates module</a>', ['@url' => Url::fromRoute($redirect_route)->toString()] ); $form['manual_updates']['#prefix'] = $core_updates_message; } } } /** * Implements hook_form_FORM_ID_alter() for 'update_settings' form. */ function automatic_updates_form_update_settings_alter(array &$form, FormStateInterface $form_state, string $form_id) { $recommender = new UpdateRecommender(); $drupal_project = $recommender->getProjectInfo(); $version = ExtensionVersion::createFromVersionString($drupal_project['existing_version']); $current_minor = $version->getMajorVersion() . '.' . $version->getMinorVersion(); $supported_until_version = $version->getMajorVersion() . '.' . ((int) $version->getMinorVersion() + ProjectSecurityData::CORE_MINORS_WITH_SECURITY_COVERAGE) . '.0'; $form['automatic_updates_cron'] = [ '#type' => 'radios', '#title' => t('Automatically update Drupal core'), '#options' => [ CronUpdater::DISABLED => t('Disabled'), CronUpdater::ALL => t('All supported updates'), CronUpdater::SECURITY => t('Security updates only'), ], '#default_value' => \Drupal::config('automatic_updates.settings')->get('cron'), '#description' => t( 'If enabled, Drupal core will be automatically updated when an update is available. Automatic updates are only supported for @current_minor.x versions of Drupal core. Drupal @current_minor will receive security updates until @supported_until_version is released.', [ '@current_minor' => $current_minor, '@supported_until_version' => $supported_until_version, ] ), ]; $form += [ '#submit' => ['::submitForm'], ]; $form['#submit'][] = '_automatic_updates_update_settings_form_submit'; } /** * Submit function for the 'update_settings' form. */ function _automatic_updates_update_settings_form_submit(array &$form, FormStateInterface $form_state) { \Drupal::configFactory() ->getEditable('automatic_updates.settings') ->set('cron', $form_state->getValue('automatic_updates_cron')) ->save(); } /** * Implements hook_local_tasks_alter(). */ function automatic_updates_local_tasks_alter(array &$local_tasks) { // The Update module's update form only allows updating modules and themes // via archive files, which could produce unexpected results on a site using // our Composer-based updater. $new_routes = [ 'update.report_update' => 'automatic_updates.report_update', 'update.module_update' => 'automatic_updates.module_update', 'update.theme_update' => 'automatic_updates.theme_update', ]; foreach ($new_routes as $local_task_id => $new_route) { if (!empty($local_tasks[$local_task_id])) { $local_tasks[$local_task_id]['route_name'] = $new_route; } } }