From 5c6ac6dddc703dfa1ff93b1e5ea67f6bb1dbf93f Mon Sep 17 00:00:00 2001 From: lucashedding <lucashedding@1463982.no-reply.drupal.org> Date: Wed, 23 Oct 2019 15:24:59 -0600 Subject: [PATCH] Issue #3089753 by heddn: Run in-place updates via cron --- automatic_updates.module | 24 +++++ config/install/automatic_updates.settings.yml | 2 + config/schema/automatic_updates.schema.yml | 6 ++ src/Form/SettingsForm.php | 96 ++++++++++++------- 4 files changed, 96 insertions(+), 32 deletions(-) diff --git a/automatic_updates.module b/automatic_updates.module index 94c66ca60c..3bb5271545 100644 --- a/automatic_updates.module +++ b/automatic_updates.module @@ -75,6 +75,30 @@ function automatic_updates_cron() { foreach ($checker->getCategories() as $category) { $checker->run($category); } + // In-place updates won't function for dev releases of Drupal core. + if (strpos(\Drupal::VERSION, '-dev') !== FALSE) { + return; + } + /** @var \Drupal\Core\Config\ImmutableConfig $config */ + $config = \Drupal::config('automatic_updates.settings'); + if ($config->get('enable_cron_updates')) { + \Drupal::service('update.manager')->refreshUpdateData(); + $available = update_get_available(TRUE); + $data = update_calculate_project_data($available); + $not_recommended = $data['drupal']['existing_version'] !== $data['drupal']['recommended']; + if ($config->get('enable_cron_security_updates')) { + if ($not_recommended && isset($data['drupal']['security updates'])) { + /** @var \Drupal\automatic_updates\Services\UpdateInterface $updater */ + $updater = \Drupal::service('automatic_updates.update'); + $updater->update('drupal', 'core', \Drupal::VERSION, $data['drupal']['latest_version']); + } + } + elseif ($not_recommended) { + /** @var \Drupal\automatic_updates\Services\UpdateInterface $updater */ + $updater = \Drupal::service('automatic_updates.update'); + $updater->update('drupal', 'core', \Drupal::VERSION, $data['drupal']['latest_version']); + } + } } /** diff --git a/config/install/automatic_updates.settings.yml b/config/install/automatic_updates.settings.yml index 5386402ba3..d3cc904507 100644 --- a/config/install/automatic_updates.settings.yml +++ b/config/install/automatic_updates.settings.yml @@ -6,3 +6,5 @@ enable_readiness_checks: true hashes_uri: 'https://updates.drupal.org/release-hashes' ignored_paths: "modules/*\nthemes/*\nprofiles/*" download_uri: 'https://www.drupal.org/in-place-updates' +enable_cron_updates: false +enable_cron_security_updates: false diff --git a/config/schema/automatic_updates.schema.yml b/config/schema/automatic_updates.schema.yml index 88a2ed4430..d3197e6038 100644 --- a/config/schema/automatic_updates.schema.yml +++ b/config/schema/automatic_updates.schema.yml @@ -26,3 +26,9 @@ automatic_updates.settings: download_uri: type: string label: 'URI for downloading in-place update assets' + enable_cron_updates: + type: boolean + label: 'Enable automatic updates via cron' + enable_cron_security_updates: + type: boolean + label: 'Enable automatic updates for security releases via cron' diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php index 326e6b9efa..0f304ce7dd 100644 --- a/src/Form/SettingsForm.php +++ b/src/Form/SettingsForm.php @@ -32,6 +32,13 @@ class SettingsForm extends ConfigFormBase { */ protected $drupalRoot; + /** + * The update manager service. + * + * @var \Drupal\update\UpdateManagerInterface + */ + protected $updateManager; + /** * {@inheritdoc} */ @@ -40,6 +47,7 @@ class SettingsForm extends ConfigFormBase { $instance->checker = $container->get('automatic_updates.readiness_checker'); $instance->dateFormatter = $container->get('date.formatter'); $instance->drupalRoot = (string) $container->get('app.root'); + $instance->updateManager = $container->get('update.manager'); return $instance; } @@ -102,45 +110,65 @@ class SettingsForm extends ConfigFormBase { ], ]; + $this->updateManager->refreshUpdateData(); + $available = update_get_available(TRUE); + $data = update_calculate_project_data($available); + $not_recommended = $data['drupal']['existing_version'] !== $data['drupal']['recommended']; + $security_update = isset($data['drupal']['security updates']); + $no_dev_core = strpos(\Drupal::VERSION, '-dev') === FALSE; $form['experimental'] = [ '#type' => 'details', - '#title' => t('Experimental'), + '#title' => $this->t('Experimental'), + '#states' => [ + 'visible' => [ + ':input[name="enable_readiness_checks"]' => ['checked' => TRUE], + ], + ], ]; + if ($not_recommended && $security_update && $no_dev_core) { + $form['experimental']['security'] = [ + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => $this->t('A security update is available for your version of Drupal.'), + ]; + } + + $update_text = $this->t('Even with all that caution, if you want to try it out... <i>no update is available at this time. Check back later once a newer release is provided for a link to update your site.</i>'); + if ($not_recommended && $no_dev_core) { + $update_text = $this->t('Even with all that caution, if you want to try it out, <a href="@link">update now</a>.', [ + '@link' => Url::fromRoute('automatic_updates.inplace-update', [ + 'project' => 'drupal', + 'type' => 'core', + 'from' => \Drupal::VERSION, + 'to' => $data['drupal']['latest_version'], + ])->toString(), + ]); + } + $form['experimental']['update'] = [ + '#prefix' => 'Database updates are not run after an update. This module does not have a stable release and it is recommended to not use these features on a live website. Use at your own risk.', '#type' => 'html_tag', '#tag' => 'p', - '#value' => $this->t('No update for Drupal is available for version %version.', ['%version' => \Drupal::VERSION]), + '#value' => $update_text, + ]; + + $form['experimental']['enable_cron_updates'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable automatic updates of Drupal core via cron.'), + '#default_value' => $config->get('enable_cron_updates'), + '#description' => $this->t('As an alternative to the full control of manually executing an update, enable automated updates via cron.'), + ]; + $form['experimental']['enable_cron_security_updates'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable security only updates'), + '#default_value' => $config->get('enable_cron_security_updates'), + '#description' => $this->t('Enable automated updates via cron for security-only releases of Drupal core.'), + '#states' => [ + 'visible' => [ + ':input[name="enable_cron_updates"]' => ['checked' => TRUE], + ], + ], ]; - if (strpos(\Drupal::VERSION, '-dev') === FALSE) { - \Drupal::service('update.manager')->refreshUpdateData(); - $available = update_get_available(TRUE); - $data = update_calculate_project_data($available); - // If we aren't on the recommended version for our version of Drupal, then - // enable this experimental feature. - if ($data['drupal']['existing_version'] !== $data['drupal']['recommended']) { - if (isset($data['drupal']['security updates'])) { - $form['experimental']['security'] = [ - '#type' => 'html_tag', - '#tag' => 'p', - '#value' => $this->t('A security update is available for your version of Drupal.'), - '#weight' => -1, - ]; - } - $form['experimental']['update'] = [ - '#type' => 'html_tag', - '#tag' => 'p', - '#value' => $this->t('Even with all that caution, if you want to try it out, <a href="@link">update now</a>.', [ - '@link' => Url::fromRoute('automatic_updates.inplace-update', [ - 'project' => 'drupal', - 'type' => 'core', - 'from' => \Drupal::VERSION, - 'to' => $data['drupal']['latest_version'], - ])->toString(), - ]), - '#prefix' => 'Note: Might break the site. No readiness checks or anything in place. Just update the files of Drupal core. Database updates are not run.', - ]; - } - } return parent::buildForm($form, $form_state); } @@ -154,6 +182,10 @@ class SettingsForm extends ConfigFormBase { $config = $this->config('automatic_updates.settings'); foreach ($form_state->getValues() as $key => $value) { $config->set($key, $value); + // Disable cron automatic updates if readiness checks are disabled. + if (in_array($key, ['enable_cron_updates', 'enable_cron_security_updates'], TRUE) && !$form_state->getValue('enable_readiness_checks')) { + $config->set($key, FALSE); + } } $config->save(); } -- GitLab