From 7c03f38efe3afdffd580686eccc37039019ee15b Mon Sep 17 00:00:00 2001 From: pookmish Date: Thu, 12 Oct 2023 13:50:13 -0500 Subject: [PATCH] fixed event subscriber (#303) --- src/EventSubscriber/EventSubscriber.php | 78 ++++++++++++++++++- .../EventSubscriber/EventSubscriberTest.php | 13 +++- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/EventSubscriber/EventSubscriber.php b/src/EventSubscriber/EventSubscriber.php index 050f753ed..73ca2fbed 100644 --- a/src/EventSubscriber/EventSubscriber.php +++ b/src/EventSubscriber/EventSubscriber.php @@ -4,16 +4,24 @@ use Acquia\DrupalEnvironmentDetector\AcquiaDrupalEnvironmentDetector; use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\Installer\InstallerKernel; use Drupal\Core\Logger\LoggerChannelFactoryInterface; +use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\StreamWrapper\StreamWrapperManager; +use Drupal\Core\Url; use Drupal\core_event_dispatcher\EntityHookEvents; use Drupal\core_event_dispatcher\Event\Entity\EntityDeleteEvent; use Drupal\core_event_dispatcher\Event\Entity\EntityInsertEvent; +use Drupal\core_event_dispatcher\Event\Entity\EntityPresaveEvent; +use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; use Drupal\default_content\Event\DefaultContentEvents; use Drupal\default_content\Event\ImportEvent; use Drupal\file\FileInterface; use Drupal\user\RoleInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; /** * Class EventSubscriber. @@ -49,7 +57,9 @@ public static function getSubscribedEvents() { return [ DefaultContentEvents::IMPORT => 'onContentImport', EntityHookEvents::ENTITY_INSERT => 'onEntityInsert', + EntityHookEvents::ENTITY_PRE_SAVE => 'onEntityPreSave', EntityHookEvents::ENTITY_DELETE => 'onEntityDelete', + KernelEvents::REQUEST => 'onKernelRequest', ]; } @@ -60,8 +70,10 @@ public static function getSubscribedEvents() { * File system service. * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory * Logger factory service. + * @param \Drupal\Core\Messenger\MessengerInterface $messenger + * Messenger service. */ - public function __construct(protected FileSystemInterface $fileSystem, LoggerChannelFactoryInterface $logger_factory) { + public function __construct(protected FileSystemInterface $fileSystem, LoggerChannelFactoryInterface $logger_factory, protected MessengerInterface $messenger) { $this->logger = $logger_factory->get('cardinal_service_profile'); } @@ -77,6 +89,70 @@ public function onEntityInsert(EntityInsertEvent $event) { } } + /** + * On saving the config page, set the renewal date field. + * + * @param \Drupal\core_event_dispatcher\Event\Entity\EntityPresaveEvent $event + * Entity presave event. + */ + public function onEntityPreSave(EntityPresaveEvent $event) { + $entity = $event->getEntity(); + if ( + $entity->getEntityTypeId() == 'config_pages' && + $entity->bundle() == 'stanford_basic_site_settings' + ) { + $renewal_date = time() + (InstallerKernel::installationAttempted() ? 0 : 60 * 60 * 24 * 365); + $entity->set('su_site_renewal_due', date(DateTimeItemInterface::DATETIME_STORAGE_FORMAT, $renewal_date)); + } + } + + /** + * On kernel request, redirect the user to update contact information. + * + * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event + * Triggered event. + */ + public function onKernelRequest(RequestEvent $event) { + $current_uri = $event->getRequest()->getRequestUri(); + + if ( + $current_uri != '/admin/config/system/basic-site-settings' && + self::redirectUser() + ) { + $config_page_url = Url::fromRoute('config_pages.stanford_basic_site_settings'); + $this->messenger->addWarning('Please update or verify the site contact information.'); + $event->setResponse(new RedirectResponse($config_page_url->toString() . '#contact')); + } + } + + /** + * Check if the current user should be redirected to the site settings form. + * + * @return bool + * Redirect the user. + */ + protected static function redirectUser() { + $cache = \Drupal::cache(); + if ($cache_data = $cache->get('su_renew_site')) { + return $cache_data->data; + } + + /** @var \Drupal\config_pages\ConfigPagesLoaderServiceInterface $config_page_loader */ + $config_page_loader = \Drupal::service('config_pages.loader'); + $renewal_date = $config_page_loader->getValue('stanford_basic_site_settings', 'su_site_renewal_due', 0, 'value') ?: date(DateTimeItemInterface::DATETIME_STORAGE_FORMAT); + + // Check for config page edit access and ignore if the user is an + // administrator. That way devs don't get forced into submitting the form. + $current_user = \Drupal::currentUser(); + $site_manager = $current_user->hasPermission('edit stanford_basic_site_settings config page entity') && !in_array('administrator', $current_user->getRoles()); + + // If the renewal date has passed, they should be redirected. + $needs_renewal = !getenv('CI') && $site_manager && (strtotime($renewal_date) - time() < 60 * 60 * 24); + $cache->set('su_renew_site', $needs_renewal, time() + 60 * 60 * 24); + + return $needs_renewal; + } + /** * On entity delete event. * diff --git a/tests/src/Kernel/EventSubscriber/EventSubscriberTest.php b/tests/src/Kernel/EventSubscriber/EventSubscriberTest.php index 2abf1990f..943570a99 100644 --- a/tests/src/Kernel/EventSubscriber/EventSubscriberTest.php +++ b/tests/src/Kernel/EventSubscriber/EventSubscriberTest.php @@ -4,19 +4,24 @@ use Drupal\config_pages\ConfigPagesLoaderServiceInterface; use Drupal\consumers\Entity\Consumer; -use Drupal\Core\File\FileSystemInterface; -use Drupal\Core\Logger\LoggerChannelFactoryInterface; +use Drupal\Core\Session\AccountProxyInterface; +use Drupal\core_event_dispatcher\Event\Entity\EntityInsertEvent; use Drupal\default_content\Event\ImportEvent; use Drupal\file\Entity\File; use Drupal\KernelTests\KernelTestBase; use Drupal\media\Entity\Media; use Drupal\media\Entity\MediaType; use Drupal\cardinal_service_profile\EventSubscriber\EventSubscriber as StanfordEventSubscriber; +use Drupal\user\Entity\Role; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Class EventSubscriberTest. * - * @group stanford_profile + * @group cardinal_service_profile * @coversDefaultClass \Drupal\cardinal_service_profile\EventSubscriber\EventSubscriber */ class EventSubscriberTest extends KernelTestBase { @@ -42,7 +47,7 @@ class EventSubscriberTest extends KernelTestBase { /** * Event subscriber object. * - * @var \Drupal\stanford_profile\EventSubscriber\EventSubscriber + * @var \Drupal\cardinal_service_profile\EventSubscriber\EventSubscriber */ protected $eventSubscriber;