From 7b55c6b40977128b61c2fee98dc744547148ba1e Mon Sep 17 00:00:00 2001 From: phenaproxima <phenaproxima@205645.no-reply.drupal.org> Date: Wed, 15 Jun 2022 19:43:09 +0000 Subject: [PATCH] Issue #3285491 by phenaproxima, Theresa.Grannum, tedbow: Send an email when a cron update succeeds --- automatic_updates.module | 16 +++++++++++++ automatic_updates.services.yml | 2 ++ src/CronUpdater.php | 35 +++++++++++++++++++++++++++- tests/src/Kernel/CronUpdaterTest.php | 24 +++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/automatic_updates.module b/automatic_updates.module index 9e4065f6a3..17b39d9db6 100644 --- a/automatic_updates.module +++ b/automatic_updates.module @@ -34,6 +34,22 @@ function automatic_updates_help($route_name, RouteMatchInterface $route_match) { } } +/** + * Implements hook_mail(). + */ +function automatic_updates_mail(string $key, array &$message, array $params): void { + if ($key === 'cron_successful') { + $message['subject'] = t("Drupal core was successfully updated"); + $message['body'][] = t('Congratulations!'); + $message['body'][] = t('Drupal core was automatically updated from @previous_version to @updated_version.', [ + '@previous_version' => $params['previous_version'], + '@updated_version' => $params['updated_version'], + ]); + $message['body'][] = t('This e-mail was sent by the Automatic Updates module, which is an experimental module. Furthermore, unattended updates are not yet fully supported.'); + $message['body'][] = t('If you are using this feature in production, it is strongly recommended for you to visit your site and ensure that everything still looks good.'); + } +} + /** * Implements hook_page_top(). */ diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index 5ac683429c..00e0493964 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -31,6 +31,8 @@ services: arguments: - '@automatic_updates.release_chooser' - '@logger.factory' + - '@plugin.manager.mail' + - '@language_manager' - '@config.factory' - '@package_manager.path_locator' - '@package_manager.beginner' diff --git a/src/CronUpdater.php b/src/CronUpdater.php index 116b17e287..744c5c31d2 100644 --- a/src/CronUpdater.php +++ b/src/CronUpdater.php @@ -2,7 +2,9 @@ namespace Drupal\automatic_updates; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; +use Drupal\Core\Mail\MailManagerInterface; use Drupal\package_manager\Exception\StageValidationException; /** @@ -58,6 +60,20 @@ class CronUpdater extends Updater { */ protected $releaseChooser; + /** + * The mail manager service. + * + * @var \Drupal\Core\Mail\MailManagerInterface + */ + protected $mailManager; + + /** + * The language manager service. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + /** * Constructs a CronUpdater object. * @@ -65,13 +81,19 @@ class CronUpdater extends Updater { * The cron release chooser service. * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory * The logger channel factory. + * @param \Drupal\Core\Mail\MailManagerInterface $mail_manager + * The mail manager service. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager service. * @param mixed ...$arguments * Additional arguments to pass to the parent constructor. */ - public function __construct(ReleaseChooser $release_chooser, LoggerChannelFactoryInterface $logger_factory, ...$arguments) { + public function __construct(ReleaseChooser $release_chooser, LoggerChannelFactoryInterface $logger_factory, MailManagerInterface $mail_manager, LanguageManagerInterface $language_manager, ...$arguments) { parent::__construct(...$arguments); $this->releaseChooser = $release_chooser; $this->logger = $logger_factory->get('automatic_updates'); + $this->mailManager = $mail_manager; + $this->languageManager = $language_manager; } /** @@ -137,6 +159,17 @@ class CronUpdater extends Updater { '%target_version' => $target_version, ] ); + + // Send notifications about the successful update. + $mail_params = [ + 'previous_version' => $installed_version, + 'updated_version' => $target_version, + ]; + $recipients = $this->configFactory->get('update.settings') + ->get('notification.emails'); + foreach ($recipients as $recipient) { + $this->mailManager->mail('automatic_updates', 'cron_successful', $recipient, $this->languageManager->getDefaultLanguage()->getId(), $mail_params); + } } catch (\Throwable $e) { $this->logger->error($e->getMessage()); diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdaterTest.php index fbca84f421..3aec58c375 100644 --- a/tests/src/Kernel/CronUpdaterTest.php +++ b/tests/src/Kernel/CronUpdaterTest.php @@ -7,6 +7,7 @@ use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Form\FormState; use Drupal\Core\Logger\RfcLogLevel; +use Drupal\Core\Test\AssertMailTrait; use Drupal\package_manager\Event\PostApplyEvent; use Drupal\package_manager\Event\PostCreateEvent; use Drupal\package_manager\Event\PostDestroyEvent; @@ -30,6 +31,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; */ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase { + use AssertMailTrait; use PackageManagerBypassTestTrait; /** @@ -352,4 +354,26 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase { ->begin(['drupal' => '9.8.1']); } + /** + * Tests that user 1 is emailed when an unattended update succeeds. + */ + public function testEmailOnSuccess(): void { + // Use a virtual project so that the test is unaffected by symlinks or other + // artifacts that might be in the running code base. + $this->createTestProject(); + + $this->config('update.settings') + ->set('notification.emails', [ + 'emissary@deep.space', + ]) + ->save(); + + $this->container->get('cron')->run(); + + // Check that we actually sent a success email to the right person. + $this->assertMail('to', 'emissary@deep.space'); + $this->assertMail('subject', "Drupal core was successfully updated"); + $this->assertMailString('body', "Congratulations!\n\nDrupal core was automatically updated from 9.8.0 to 9.8.1.\n", 1); + } + } -- GitLab