diff --git a/modules/group_recurring_events_series/group_recurring_events_series.module b/modules/group_recurring_events_series/group_recurring_events_series.module index e50e979542f2eb0e7f407193e85854a2c5708123..d98db0fc4bfd4ff77f4b964a7f05738129cb8cae 100644 --- a/modules/group_recurring_events_series/group_recurring_events_series.module +++ b/modules/group_recurring_events_series/group_recurring_events_series.module @@ -42,3 +42,12 @@ function group_recurring_events_series_entity_operation(EntityInterface $entity) return $operations; } + +/* + * hook_entity_type_build + */ +function group_recurring_events_series_entity_type_build(array &$entity_types) { + if(isset($entity_types['eventinstance'])) { + $entity_types['eventinstance']->setHandlerClass('access', 'Drupal\group_recurring_events_series\Access\GroupEventInstanceHandler'); + } +} diff --git a/modules/group_recurring_events_series/src/Access/.gitkeep b/modules/group_recurring_events_series/src/Access/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/modules/group_recurring_events_series/src/Access/GroupEventInstanceHandler.php b/modules/group_recurring_events_series/src/Access/GroupEventInstanceHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..2922bd15870ccd343d8c21350fc5174d31272fd7 --- /dev/null +++ b/modules/group_recurring_events_series/src/Access/GroupEventInstanceHandler.php @@ -0,0 +1,27 @@ +<?php + +namespace Drupal\group_recurring_events_series\Access; + +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Entity\EntityAccessControlHandler; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Session\AccountInterface; + +use Drupal\recurring_events\Entity\EventSeries; +use Drupal\recurring_events\EventInstanceAccessControlHandler; + +class GroupEventInstanceHandler extends EventInstanceAccessControlHandler { + protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { + $result = parent::checkAccess($entity, $operation, $account); + if(!$result->isAllowed()) { + // Need GroupContentAccessControlHandler not EventSeriesAccessControlHandler + $manager = \Drupal::service('plugin.manager.group_content_enabler'); + $type = 'group_recurring_events_series:' . $entity->getType(); + if($manager->hasHandler($type, 'access')) { + $handler = $manager->getAccessControlHandler($type); + $result = $handler->entityAccess($entity->getEventSeries(), $operation, $account, TRUE); + } + } + return $result; + } +} diff --git a/modules/recurring_events_registration/modules/recurring_events_reminders/recurring_events_reminders.module b/modules/recurring_events_registration/modules/recurring_events_reminders/recurring_events_reminders.module index 7982d2530be71ef4b4d691a7e9e2fb50440511fa..3e5b246f7d0b7b0a4df8ae5123af74b247c54c9d 100644 --- a/modules/recurring_events_registration/modules/recurring_events_reminders/recurring_events_reminders.module +++ b/modules/recurring_events_registration/modules/recurring_events_reminders/recurring_events_reminders.module @@ -137,6 +137,7 @@ function recurring_events_reminders_cron() { ->condition('reminder_date', NULL, 'IS NOT NULL') ->condition('reminder_sent', NULL, 'IS NULL') ->condition('reminder_date', time(), '<=') + ->accessCheck(FALSE) ->execute(); if (!empty($event_instances)) { @@ -153,6 +154,7 @@ function recurring_events_reminders_cron() { $registration_creation_service->setEventInstance($instance); $registrants = $registration_creation_service->retrieveRegisteredParties(); + if (empty($registrants)) { return; } @@ -161,7 +163,8 @@ function recurring_events_reminders_cron() { // Send an email to all registrants. foreach ($registrants as $registrant) { - recurring_events_registration_send_notification($key, $registrant); + // Add each notification to be sent to the queue. + \Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant); } } } diff --git a/modules/recurring_events_registration/recurring_events_registration.install b/modules/recurring_events_registration/recurring_events_registration.install index e950bff77b0fe3dd7fff605c83f16cc4888300bf..da89866f9738eb5040d2c96e2f7216968be313e5 100644 --- a/modules/recurring_events_registration/recurring_events_registration.install +++ b/modules/recurring_events_registration/recurring_events_registration.install @@ -116,6 +116,7 @@ function recurring_events_registration_update_8003() { $registration_values = $database->select($table_name) ->fields($table_name, [$id_key, $revision_key] + $reg_fields) + ->accessCheck(FALSE) ->execute() ->fetchAll(); @@ -123,6 +124,7 @@ function recurring_events_registration_update_8003() { $database->update($table_name) ->fields($update_fields) + ->accessCheck(FALSE) ->execute(); $field_storage_definition = $definition_manager->getFieldStorageDefinition('event_registration', 'eventseries'); @@ -166,11 +168,13 @@ function recurring_events_registration_update_8003() { $database->update($table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) + ->accessCheck(FALSE) ->execute(); $database->update($revision_table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) + ->accessCheck(FALSE) ->execute(); } } @@ -235,6 +239,7 @@ function recurring_events_registration_update_8006(&$sandbox) { $registrants = \Drupal::entityTypeManager() ->getStorage('registrant') ->getQuery() + ->accessCheck(FALSE) ->execute(); $sandbox['registrants'] = $registrants; @@ -302,6 +307,7 @@ function recurring_events_registration_update_8007() { $registration_values = $database->select($table_name) ->fields($table_name, [$id_key, $revision_key] + $reg_fields) ->condition('event_registration__registration', 1) + ->accessCheck(FALSE) ->execute() ->fetchAll(); @@ -310,6 +316,7 @@ function recurring_events_registration_update_8007() { $update_fields = array_fill_keys($reg_fields, NULL); $database->update($table_name) ->fields($update_fields) + ->accessCheck(FALSE) ->execute(); // Remove the existing registration field. @@ -349,12 +356,14 @@ function recurring_events_registration_update_8007() { $database->update($table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) + ->accessCheck(FALSE) ->execute(); $database->update($revision_table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) ->condition($revision_key, $value->{$revision_key}) + ->accessCheck(FALSE) ->execute(); } } @@ -443,6 +452,7 @@ function recurring_events_registration_update_8009() { $registration_values = $database->select($table_name) ->fields($table_name, [$id_key, $revision_key] + $reg_fields) ->condition('event_registration__registration', 1) + ->accessCheck(FALSE) ->execute() ->fetchAll(); @@ -451,6 +461,7 @@ function recurring_events_registration_update_8009() { $update_fields = array_fill_keys($reg_fields, NULL); $database->update($table_name) ->fields($update_fields) + ->accessCheck(FALSE) ->execute(); // Remove the existing registration field. @@ -490,12 +501,14 @@ function recurring_events_registration_update_8009() { $database->update($table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) + ->accessCheck(FALSE) ->execute(); $database->update($revision_table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) ->condition($revision_key, $value->{$revision_key}) + ->accessCheck(FALSE) ->execute(); } } diff --git a/modules/recurring_events_registration/recurring_events_registration.module b/modules/recurring_events_registration/recurring_events_registration.module index e5959ad625bafb27185560c9b9df72294de82dfc..3ba086a6d662b62cc8eab22fa41025657a8bcc35 100644 --- a/modules/recurring_events_registration/recurring_events_registration.module +++ b/modules/recurring_events_registration/recurring_events_registration.module @@ -143,26 +143,47 @@ function template_preprocess_registrant(array &$variables) { * Implements hook_mail(). */ function recurring_events_registration_mail($key, &$message, $params) { - /** @var \Drupal\recurring_events_registration\NotificationService */ - $service = \Drupal::service('recurring_events_registration.notification_service'); - $service->setKey($key)->setEntity($params['registrant']); - - if ($service->isEnabled()) { - if (!empty($params['subject'])) { - $service->setSubject($params['subject']); - } - if (!empty($params['body'])) { - $service->setMessage($params['body']); - } - if (!empty($params['from'])) { - $service->setFrom($params['from']); - } + // Only if a value for 'subject', 'body' or 'from' has not been received in + // the `$params`, then use the notification service which is able to get + // those values from the `$key` and the `$registrant`. + // Some pieces of code can call the `mail()` function with already proccessed + // values for 'subject', 'body' and 'from', meaning that it is not necessary + // that those values are calculated here by the notification service. + // @see \Drupal\recurring_events_registration\Plugin\QueueWorker\EmailNotificationsQueueWorker + if ((empty($params['subject']) || empty($params['body']) || empty($params['from'])) + && !empty($params['registrant']) + && $params['registrant'] instanceof Registrant) { + /** @var \Drupal\recurring_events_registration\NotificationService $service */ + $service = \Drupal::service('recurring_events_registration.notification_service'); + $service->setKey($key)->setEntity($params['registrant']); + } + // If other pieces of code that have called the `mail()` function have + // already defined those params, give them precedence. Else, let the + // notification service to calculate those values. + // Set the `$message['from']`. + if (!empty($params['from'])) { + $message['from'] = $params['from']; + } + elseif (isset($service)) { $message['from'] = $service->getFrom(); + } + + // Set the `$message['subject']`. + if (!empty($params['subject'])) { + $message['subject'] = $params['subject']; + } + elseif (isset($service)) { $message['subject'] = $service->getSubject(); + } + + // Set the `$message['body']`. + if (!empty($params['body'])) { + $message['body'][] = $params['body']; + } + elseif (isset($service)) { $message['body'][] = $service->getMessage(); } - return FALSE; } /** @@ -218,7 +239,8 @@ function recurring_events_registration_recurring_events_save_pre_instances_delet // Send an email to all registrants. foreach ($registrants as $registrant) { - recurring_events_registration_send_notification($key, $registrant); + // Add each notification to be sent to the queue. + \Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant); $registrant->delete(); } } @@ -250,7 +272,8 @@ function recurring_events_registration_entity_update(EntityInterface $entity) { // Send an email to all registrants. foreach ($registrants as $registrant) { - recurring_events_registration_send_notification($key, $registrant); + // Add each notification to be sent to the queue. + \Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant); } } } @@ -274,7 +297,8 @@ function recurring_events_registration_recurring_events_pre_delete_instance(Even foreach ($registrants as $registrant) { // Only send email notifications if this event instance is in the future. if ($registration_creation_service->eventInstanceIsInFuture()) { - recurring_events_registration_send_notification($key, $registrant); + // Add each notification to be sent to the queue. + \Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant); } $registrant->delete(); } @@ -296,7 +320,8 @@ function recurring_events_registration_recurring_events_pre_delete_instances(Eve // Send an email to the future registrants. foreach ($future_registrants as $registrant) { - recurring_events_registration_send_notification($key, $registrant); + // Add each notification to be sent to the queue. + \Drupal::service('recurring_events_registration.notification_service')->addEmailNotificationToQueue($key, $registrant); } } @@ -428,6 +453,7 @@ function recurring_events_registration_registrant_insert(EntityInterface $entity ->condition('sourceEntityType', ['eventseries', 'eventinstance'], 'IN') ->condition('destinationEntityType', $entity_type) ->condition('destinationEntityBundle', $bundle) + ->accessCheck(FALSE) ->execute(); if (!empty($inherited_field_ids)) { diff --git a/modules/recurring_events_registration/recurring_events_registration.services.yml b/modules/recurring_events_registration/recurring_events_registration.services.yml index d5dd368e78f204c3395da7ca221056e55f0b987d..7572820796e9fca02895e7558d909fdb224cf578 100644 --- a/modules/recurring_events_registration/recurring_events_registration.services.yml +++ b/modules/recurring_events_registration/recurring_events_registration.services.yml @@ -4,7 +4,7 @@ services: arguments: ['@string_translation', '@database', '@logger.factory', '@messenger', '@entity_type.manager', '@module_handler', '@token'] recurring_events_registration.notification_service: class: Drupal\recurring_events_registration\NotificationService - arguments: ['@string_translation', '@config.factory', '@logger.factory', '@messenger', '@token', '@module_handler', '@recurring_events_registration.creation_service'] + arguments: ['@string_translation', '@config.factory', '@logger.factory', '@messenger', '@token', '@module_handler', '@recurring_events_registration.creation_service', '@queue'] recurring_events_registration.access_handler: class: Drupal\recurring_events_registration\AccessHandler arguments: ['@string_translation', '@recurring_events_registration.creation_service', '@current_route_match', '@entity_type.manager'] @@ -12,4 +12,4 @@ services: class: Drupal\recurring_events_registration\Routing\RouteSubscriber arguments: [ '@config.factory' ] tags: - - { name: event_subscriber } + - { name: event_subscriber } \ No newline at end of file diff --git a/modules/recurring_events_registration/recurring_events_registration.tokens.inc b/modules/recurring_events_registration/recurring_events_registration.tokens.inc index 83a1150bedf734d51fd02f884e1e5769d70ff403..569ead78a1830c89831d570776e9f11186b53b50 100644 --- a/modules/recurring_events_registration/recurring_events_registration.tokens.inc +++ b/modules/recurring_events_registration/recurring_events_registration.tokens.inc @@ -50,6 +50,17 @@ function recurring_events_registration_token_info() { 'description' => t('The URL to delete a registrant.'), ]; + $registrant['eventinstance'] = [ + 'name' => t('Registrant event instance'), + 'description' => t('The eventinstance associated with a registrant'), + 'type' => 'eventinstance', + ]; + $registrant['eventseries'] = [ + 'name' => t('Registrant event series'), + 'description' => t('The eventseries associated with a registrant'), + 'type' => 'eventseries', + ]; + return [ 'types' => [ 'eventinstance' => $eventinstance_type, @@ -67,6 +78,7 @@ function recurring_events_registration_token_info() { * Implements hook_tokens(). */ function recurring_events_registration_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { + $token_service = \Drupal::token(); $replacements = []; if ($type == 'eventinstance' && !empty($data['eventinstance'])) { $event_instance = $data['eventinstance']; @@ -108,8 +120,30 @@ function recurring_events_registration_tokens($type, $tokens, array $data, array } $replacements[$original] = $url; break; + + case 'eventinstance': + $instance = $registrant->getEventInstance(); + $bubbleable_metadata->addCacheableDependency($instance); + $replacements[$original] = $instance->label(); + break; + + case 'eventseries': + $series = $registrant->getEventSeries(); + $bubbleable_metadata->addCacheableDependency($series); + $replacements[$original] = $series->label(); + break; } } + + if ($instance_tokens = $token_service->findWithPrefix($tokens, 'eventinstance')) { + $instance = $registrant->getEventInstance(); + $replacements += $token_service->generate('eventinstance', $instance_tokens, ['eventinstance' => $instance], $options, $bubbleable_metadata); + } + + if ($series_tokens = $token_service->findWithPrefix($tokens, 'eventseries')) { + $series = $registrant->getEventSeries(); + $replacements += $token_service->generate('eventseries', $series_tokens, ['eventseries' => $series], $options, $bubbleable_metadata); + } } return $replacements; } diff --git a/modules/recurring_events_registration/src/Form/OrphanedEventRegistrantsForm.php b/modules/recurring_events_registration/src/Form/OrphanedEventRegistrantsForm.php index b89886b5fd764841dd554deaf480ad2340d5dac0..dbeb3fff06d0e3c1511b4966b5afae8d37ee7671 100644 --- a/modules/recurring_events_registration/src/Form/OrphanedEventRegistrantsForm.php +++ b/modules/recurring_events_registration/src/Form/OrphanedEventRegistrantsForm.php @@ -160,6 +160,7 @@ class OrphanedEventRegistrantsForm extends FormBase { ->condition('es.id', NULL, 'IS NULL') ->condition('ei.id', NULL, 'IS NULL'); $registrants = $query->condition($or_group) + ->accessCheck(FALSE) ->execute() ->fetchCol(); diff --git a/modules/recurring_events_registration/src/NotificationService.php b/modules/recurring_events_registration/src/NotificationService.php index ac303818083aa06c74cddff0583fe862969c8782..24373e643fe88daf0cf525cd88b8283c821bd08f 100644 --- a/modules/recurring_events_registration/src/NotificationService.php +++ b/modules/recurring_events_registration/src/NotificationService.php @@ -10,6 +10,7 @@ use Drupal\Core\Utility\Token; use Drupal\recurring_events_registration\Entity\RegistrantInterface; use Drupal\Core\Extension\ModuleHandler; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Queue\QueueFactory; /** * Provides a service with helper functions to facilitate notifications. @@ -114,6 +115,13 @@ class NotificationService { */ protected $custom = FALSE; + /** + * The update fetch queue. + * + * @var \Drupal\Core\Queue\QueueFactory + */ + protected $queueFactory; + /** * Class constructor. * @@ -131,8 +139,10 @@ class NotificationService { * The module handler service. * @param \Drupal\recurring_events_registration\RegistrationCreationService $creation_service * The registration creation service. + * @param \Drupal\Core\Queue\QueueFactory $queue_factory + * The queue factory. */ - public function __construct(TranslationInterface $translation, ConfigFactory $config_factory, LoggerChannelFactoryInterface $logger, Messenger $messenger, Token $token, ModuleHandler $module_handler, RegistrationCreationService $creation_service) { + public function __construct(TranslationInterface $translation, ConfigFactory $config_factory, LoggerChannelFactoryInterface $logger, Messenger $messenger, Token $token, ModuleHandler $module_handler, RegistrationCreationService $creation_service, QueueFactory $queue_factory) { $this->translation = $translation; $this->configFactory = $config_factory; $this->loggerFactory = $logger->get('recurring_events_registration'); @@ -141,6 +151,7 @@ class NotificationService { $this->moduleHandler = $module_handler; $this->creationService = $creation_service; $this->configName = 'recurring_events_registration.registrant.config'; + $this->queueFactory = $queue_factory; } /** @@ -154,7 +165,8 @@ class NotificationService { $container->get('messenger'), $container->get('token'), $container->get('module_handler'), - $container->get('recurring_events_registration.creation_service') + $container->get('recurring_events_registration.creation_service'), + $container->get('queue') ); } @@ -246,7 +258,7 @@ class NotificationService { * @return string|bool * The key, or FALSE if not set. */ - protected function getKey() { + public function getKey() { if (empty($this->key)) { $this->messenger->addError($this->translation->translate('No key defined for @module notifications.', [ '@module' => 'recurring_events_registration', @@ -352,11 +364,7 @@ class NotificationService { public function getSubject($parse_tokens = TRUE) { $key = $this->getKey(); if ($key) { - $subject = $this->subject; - if (empty($subject)) { - $subject = $this->getConfigValue('subject'); - $this->setSubject($subject); - } + $subject = $this->getConfigValue('subject'); if (empty($subject)) { $this->messenger->addError($this->translation->translate('No default subject configured for @key emails in @config_name.', [ @@ -386,11 +394,7 @@ class NotificationService { public function getMessage($parse_tokens = TRUE) { $key = $this->getKey(); if ($key) { - $message = $this->message; - if (empty($message)) { - $message = $this->getConfigValue('body'); - $this->setMessage($message); - } + $message = $this->getConfigValue('body'); if (empty($message)) { $this->messenger->addError($this->translation->translate('No default body configured for @key emails in @config_name.', [ @@ -450,4 +454,56 @@ class NotificationService { return $this->creationService->getAvailableTokens($relevant_tokens); } + /** + * Adds an email notification to be sent later by the Queue Worker. + */ + public function addEmailNotificationToQueue($key, RegistrantInterface $registrant) { + $config = $this->configFactory->get('recurring_events_registration.registrant.config'); + $send_email = $config->get('email_notifications'); + $send_email_key = $config->get('notifications' . '.' . $key . '.enabled'); + + // Modify $send_email if necessary. + if ($registrant instanceof RegistrantInterface) { + $this->moduleHandler->alter('recurring_events_registration_send_notification', $send_email, $registrant); + } + + if ($send_email && $send_email_key) { + // We need to get the parsed email subject and message (after token + // replacement) to add them to the `$item` that will be queued. We are + // not adding the `$registrant` to the `$item`, since in the queue worker + // we cannot rely on operations over the `$registrant` or its parent + // instance or series, since at that point those entities might have been + // deleted. There are some operations and notification types that require + // the `$registrant`to be deleted, for example: the notifications + // corresponding to the keys 'series_modification_notification' and + // 'instance_deletion_notification'. + // @see recurring_events_registration_recurring_events_save_pre_instances_deletion() + // @see recurring_events_registration_recurring_events_pre_delete_instance() + $this->setKey($key)->setEntity($registrant); + $subject = $this->getSubject(); + $message = $this->getMessage(); + $from = $this->getFrom(); + + // Create the item to be added to the queue. + $item = new \stdClass(); + $item->key = $key; + $item->to = $registrant->email->value; + + $params = [ + 'subject' => $subject, + 'body' => $message, + 'from' => $from, + ]; + // Allow modules to add data to the `$params`. They can get the data from + // `$registrant`. Those `$params` are used later as the + // `$message['params']` in mail hooks. + $this->moduleHandler->alter('recurring_events_registration_message_params', $params, $registrant); + $item->params = $params; + + // Add the item to the queue. + $queue = $this->queueFactory->get('recurring_events_registration_email_notifications_queue_worker'); + $queue->createItem($item); + } + } + } diff --git a/modules/recurring_events_registration/src/Plugin/QueueWorker/EmailNotificationsQueueWorker.php b/modules/recurring_events_registration/src/Plugin/QueueWorker/EmailNotificationsQueueWorker.php new file mode 100644 index 0000000000000000000000000000000000000000..e2ab74a6f8868641215c91959cfb67aa5100498e --- /dev/null +++ b/modules/recurring_events_registration/src/Plugin/QueueWorker/EmailNotificationsQueueWorker.php @@ -0,0 +1,80 @@ +<?php + +namespace Drupal\recurring_events_registration\Plugin\QueueWorker; + +use Drupal\Core\Queue\QueueWorkerBase; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Mail\MailManagerInterface; +use Drupal\Core\Language\LanguageManagerInterface; + +/** + * Defines 'recurring_events_registration_email_notifications_queue_worker' queue worker. + * + * @QueueWorker( + * id = "recurring_events_registration_email_notifications_queue_worker", + * title = @Translation("Email Notifications Queue Worker"), + * cron = {"time" = 30} + * ) + */ +class EmailNotificationsQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface { + + /** + * The mail manager. + * + * @var \Drupal\Core\Mail\MailManagerInterface + */ + protected $mailManager; + + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * Constructs a new LocaleTranslation object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param array $plugin_definition + * @param \Drupal\Core\Mail\MailManagerInterface $mail_manager + * The mail manager. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, MailManagerInterface $mail_manager, LanguageManagerInterface $language_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->mailManager = $mail_manager; + $this->languageManager = $language_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.mail'), + $container->get('language_manager') + ); + } + + /** + * {@inheritdoc} + */ + public function processItem($item) { + if (empty($item->key) || empty($item->to) || (empty($item->params['subject']) && empty($item->params['body']))) { + return; + } + // All this worker has to do is to send the email. + // The Subject and Body already have to be included in the `$item`. + $this->mailManager->mail('recurring_events_registration', $item->key, $item->to, $this->languageManager->getDefaultLanguage()->getId(), $item->params); + } + +} diff --git a/modules/recurring_events_registration/src/RegistrantListBuilder.php b/modules/recurring_events_registration/src/RegistrantListBuilder.php index 77dd3891c5e4f7217b518fd4f722794a67566d20..e4957762279a612a1dd8a7090edd600a9bbe1f93 100644 --- a/modules/recurring_events_registration/src/RegistrantListBuilder.php +++ b/modules/recurring_events_registration/src/RegistrantListBuilder.php @@ -177,7 +177,7 @@ class RegistrantListBuilder extends EntityListBuilder { if ($this->limit) { $query->pager($this->limit); } - return $query->execute(); + return $query->accessCheck(FALSE)->execute(); } } diff --git a/recurring_events.install b/recurring_events.install index 2ce92d1eed4d96ad3209e33c8c515394ab88a278..59d86f06f533392e6c76f16328d9c83056359dc9 100644 --- a/recurring_events.install +++ b/recurring_events.install @@ -4,7 +4,7 @@ * @file * Installation and update functionality for the recurring_events module. */ - +use Drupal\views\Views; use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Field\BaseFieldDefinition; @@ -307,6 +307,7 @@ function recurring_events_update_8007() { $inherited_fields = $database->select('config', 'c') ->fields('c', ['name']) ->condition('name', 'recurring_events.field_inheritance.%', 'LIKE') + ->accessCheck(FALSE) ->execute() ->fetchCol(); $bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo('eventseries'); @@ -339,6 +340,7 @@ function recurring_events_update_8007() { } $database->delete('config') ->condition('name', 'recurring_events.field_inheritance.%', 'LIKE') + ->accessCheck(FALSE) ->execute(); } @@ -378,7 +380,7 @@ function recurring_events_update_8008() { function recurring_events_update_8009(&$sandbox) { // This is a multipass update. if (empty($sandbox['events'])) { - $events = \Drupal::entityQuery('eventinstance')->execute(); + $events = \Drupal::entityQuery('eventinstance')->accessCheck(FALSE)->execute(); $sandbox['events'] = $events; $sandbox['max'] = count($events); $sandbox['limit'] = 50; @@ -402,6 +404,7 @@ function recurring_events_update_8009(&$sandbox) { ->condition('sourceEntityType', 'eventseries') ->condition('destinationEntityType', $entity_type) ->condition('destinationEntityBundle', $bundle) + ->accessCheck(FALSE) ->execute(); if (!empty($inherited_field_ids)) { @@ -509,6 +512,7 @@ function recurring_events_update_8011() { $database->update($table) ->fields([$field => '']) ->isNull($field) + ->accessCheck(FALSE) ->execute(); } } @@ -526,6 +530,7 @@ function recurring_events_update_8011() { $database_values = $database->select($table_name) ->fields($table_name, array_merge([$id_key, $revision_key], $field_fields)) + ->accessCheck(FALSE) ->execute() ->fetchAll(); @@ -576,12 +581,14 @@ function recurring_events_update_8011() { $database->update($table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) + ->accessCheck(FALSE) ->execute(); $database->update($revision_table_name) ->fields($values_to_restore) ->condition($id_key, $value->{$id_key}) ->condition($revision_key, $value->{$revision_key}) + ->accessCheck(FALSE) ->execute(); } } @@ -604,7 +611,7 @@ function recurring_events_update_8013() { $config_factory = \Drupal::configFactory(); - if (!$views = \Drupal\views\Views::getAllViews()) { + if (!$views = Views::getAllViews()) { return []; } diff --git a/recurring_events.module b/recurring_events.module index 1324508a3c664745fc694d57a839f200eb743839..056d83bce41645c1a74c206b33f513d7613500e5 100644 --- a/recurring_events.module +++ b/recurring_events.module @@ -176,6 +176,33 @@ function recurring_events_eventseries_insert(EntityInterface $entity) { } } +/** + * Implements hook_ENTITY_TYPE_translation_insert(). + */ +function recurring_events_eventseries_translation_insert(EntityInterface $translation) { + if (\Drupal::isConfigSyncing()) { + return; + } + $creation_service = \Drupal::service('recurring_events.event_creation_service'); + $creation_service->createInstances($translation); + + $instances = $translation->event_instances->referencedEntities(); + if (!empty($instances)) { + foreach ($instances as $instance) { + if ($instance->hasTranslation($translation->language()->getId())) { + $instance = $instance->getTranslation($translation->language()->getId()); + } + $instance->set('eventseries_id', $translation->id()); + $instance->setNewRevision(FALSE); + + $creation_service->configureDefaultInheritances($instance, $translation->id()); + $creation_service->updateInstanceStatus($instance, $translation); + + $instance->save(); + } + } +} + /** * Implements hook_ENTITY_TYPE_insert(). */ @@ -381,7 +408,7 @@ function recurring_events_eventseries_type_delete(EntityInterface $entity) { ->condition($and_destination) ->condition($and_source); $query->condition($or); - $inherited_field_ids = $query->execute(); + $inherited_field_ids = $query->accessCheck(FALSE)->execute(); if (!empty($inherited_field_ids)) { $inherited_fields = \Drupal::entityTypeManager()->getStorage('field_inheritance')->loadMultiple($inherited_field_ids); @@ -403,7 +430,7 @@ function recurring_events_eventseries_type_delete(EntityInterface $entity) { ->condition($and_destination) ->condition($and_source); $query->condition($or); - $inherited_field_ids = $query->execute(); + $inherited_field_ids = $query->accessCheck(FALSE)->execute(); if (!empty($inherited_field_ids)) { $inherited_fields = \Drupal::entityTypeManager()->getStorage('field_inheritance')->loadMultiple($inherited_field_ids); @@ -428,7 +455,7 @@ function recurring_events_eventseries_type_delete(EntityInterface $entity) { ->condition($and_destination) ->condition($and_source); $query->condition($or); - $inherited_field_ids = $query->execute(); + $inherited_field_ids = $query->accessCheck(FALSE)->execute(); if (!empty($inherited_field_ids)) { $inherited_fields = \Drupal::entityTypeManager()->getStorage('field_inheritance')->loadMultiple($inherited_field_ids); @@ -727,6 +754,7 @@ function recurring_events_entity_base_field_info_alter(&$fields, EntityTypeInter 'weight' => 0, ]) ->setDisplayConfigurable('form', FALSE) + ->setTranslatable(TRUE) ->setClass(EventInstances::class); } } diff --git a/src/Entity/EventInstance.php b/src/Entity/EventInstance.php index 095cb3f482f1f7df601903133a93ba739bdae306..d6655cea834f28f6e9f42fb270e2c7d3cb08799a 100644 --- a/src/Entity/EventInstance.php +++ b/src/Entity/EventInstance.php @@ -6,8 +6,9 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Entity\EditorialContentEntityBase; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\RevisionableInterface; use Drupal\recurring_events\EventInterface; -use Drupal\user\UserInterface; +use Drupal\recurring_events\EventUserTrait; /** * Defines the Event Instance entity. @@ -105,6 +106,7 @@ use Drupal\user\UserInterface; * "uuid" = "uuid", * "label" = "title", * "bundle" = "type", + * "uid" = "uid", * }, * revision_metadata_keys = { * "revision_user" = "revision_uid", @@ -154,6 +156,8 @@ use Drupal\user\UserInterface; */ class EventInstance extends EditorialContentEntityBase implements EventInterface { + use EventUserTrait; + /** * {@inheritdoc} * @@ -234,36 +238,6 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface return $this; } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->get('uid')->target_id; - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->setOwnerId($account->id()); - return $this; - } - /** * {@inheritdoc} */ @@ -291,6 +265,7 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); // Standard field, used as unique if primary index. $fields['id'] = BaseFieldDefinition::create('integer') @@ -298,25 +273,6 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface ->setDescription(t('The ID of the event entity.')) ->setReadOnly(TRUE); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Authored by')) - ->setDescription(t('The username of the content author.')) - ->setRevisionable(TRUE) - ->setSetting('target_type', 'user') - ->setDefaultValueCallback('Drupal\recurring_events\Entity\EventInstance::getCurrentUserId') - ->setTranslatable(TRUE) - ->setDisplayOptions('form', [ - 'type' => 'entity_reference_autocomplete', - 'weight' => 5, - 'settings' => [ - 'match_operator' => 'CONTAINS', - 'size' => '60', - 'placeholder' => '', - 'match_limit' => 10, - ], - ]) - ->setDisplayConfigurable('form', TRUE); - // Standard field, unique outside of the scope of the current project. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) @@ -368,7 +324,8 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface $fields['eventseries_id'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Event Series ID')) ->setDescription(t('The ID of the event series entity.')) - ->setSetting('target_type', 'eventseries'); + ->setSetting('target_type', 'eventseries') + ->setTranslatable(TRUE); $fields['langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Language code')) @@ -410,7 +367,11 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface * The event series. */ public function getEventSeries() { - return $this->get('eventseries_id')->entity; + $entity = $this->get('eventseries_id')->entity; + if ($entity->hasTranslation($this->language()->getId())) { + return $entity->getTranslation($this->language()->getId()); + } + return $entity; } } diff --git a/src/Entity/EventSeries.php b/src/Entity/EventSeries.php index cafb5d95cdaf9a13003fabdee6b87ae5e5c81407..54190cef57fd3c399a681e5b03c905c3a850de83 100644 --- a/src/Entity/EventSeries.php +++ b/src/Entity/EventSeries.php @@ -6,7 +6,9 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Entity\EditorialContentEntityBase; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\RevisionableInterface; use Drupal\recurring_events\EventInterface; +use Drupal\recurring_events\EventUserTrait; use Drupal\user\UserInterface; /** @@ -104,6 +106,7 @@ use Drupal\user\UserInterface; * "langcode" = "langcode", * "label" = "title", * "uuid" = "uuid", + * "uid" = "uid", * "bundle" = "type", * }, * revision_metadata_keys = { @@ -156,6 +159,8 @@ use Drupal\user\UserInterface; */ class EventSeries extends EditorialContentEntityBase implements EventInterface { + use EventUserTrait; + /** * {@inheritdoc} * @@ -236,36 +241,6 @@ class EventSeries extends EditorialContentEntityBase implements EventInterface { return $this; } - /** - * {@inheritdoc} - */ - public function getOwner() { - return $this->get('uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function getOwnerId() { - return $this->get('uid')->target_id; - } - - /** - * {@inheritdoc} - */ - public function setOwnerId($uid) { - $this->set('uid', $uid); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOwner(UserInterface $account) { - $this->setOwnerId($account->id()); - return $this; - } - /** * {@inheritdoc} */ @@ -293,31 +268,13 @@ class EventSeries extends EditorialContentEntityBase implements EventInterface { */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('The ID of the eventseries entity.')) ->setReadOnly(TRUE); - $fields['uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Authored by')) - ->setDescription(t('The username of the content author.')) - ->setRevisionable(TRUE) - ->setSetting('target_type', 'user') - ->setDefaultValueCallback('Drupal\recurring_events\Entity\Event::getCurrentUserId') - ->setTranslatable(TRUE) - ->setDisplayOptions('form', [ - 'type' => 'entity_reference_autocomplete', - 'weight' => 11, - 'settings' => [ - 'match_operator' => 'CONTAINS', - 'size' => '60', - 'placeholder' => '', - 'match_limit' => 10, - ], - ]) - ->setDisplayConfigurable('form', TRUE); - $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The UUID of the event entity.')) diff --git a/src/EventCreationService.php b/src/EventCreationService.php index 1a716057af755b732dfd27a0ccb01fb1cec663cc..edb51d9a085077608aac5fcd0d8f4d63b4ce83dc 100644 --- a/src/EventCreationService.php +++ b/src/EventCreationService.php @@ -44,9 +44,9 @@ class EventCreationService { /** * Logger Factory. * - * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface + * @var \Drupal\Core\Logger\LoggerChannel */ - protected $loggerFactory; + protected $loggerChannel; /** * The messenger service. @@ -115,7 +115,7 @@ class EventCreationService { public function __construct(TranslationInterface $translation, Connection $database, LoggerChannelFactoryInterface $logger, Messenger $messenger, FieldTypePluginManager $field_type_plugin_manager, EntityFieldManager $entity_field_manager, ModuleHandler $module_handler, EntityTypeManagerInterface $entity_type_manager, KeyValueFactoryInterface $key_value) { $this->translation = $translation; $this->database = $database; - $this->loggerFactory = $logger->get('recurring_events'); + $this->loggerChannel = $logger->get('recurring_events'); $this->messenger = $messenger; $this->fieldTypePluginManager = $field_type_plugin_manager; $this->entityFieldManager = $entity_field_manager; @@ -528,8 +528,42 @@ class EventCreationService { $this->moduleHandler->alter('recurring_events_event_instance', $data); - $entity = $this->entityTypeManager->getStorage('eventinstance')->create($data); - $entity->save(); + $storage = $this->entityTypeManager->getStorage('eventinstance'); + if ($event->isDefaultTranslation()) { + $entity = $storage->create($data); + } + else { + // Grab the untranslated event series. + $original = $event->getUntranslated(); + // Find the corresponding default language event instance that matches + // the date and time of the version we wish to translate, so that we are + // mapping the translations from default language to translated language + // appropriately. + $entity_ids = $storage->getQuery() + ->condition('date__value', $data['date']['value']) + ->condition('date__end_value', $data['date']['end_value']) + ->condition('eventseries_id', $data['eventseries_id']) + ->condition('type', $data['type']) + ->condition('langcode', $original->language()->getId()) + ->accessCheck(FALSE) + ->execute(); + + if (!empty($entity_ids)) { + // Load the default language version of the event instance. + $entity = $storage->load(reset($entity_ids)); + // Only add a translation if we do not already have one. + if (!$entity->hasTranslation($event->language()->getId())) { + $entity->addTranslation($event->language()->getId(), $data); + } + } + } + + if ($entity) { + $entity->save(); + } + else { + $this->loggerChannel->warning('Missing event instance in default language. Translation could not be created'); + } return $entity; } @@ -707,13 +741,13 @@ class EventCreationService { if ($event->hasField('moderation_state') && $instance->hasField('moderation_state')) { $series_query = $this->entityTypeManager->getStorage('workflow')->getQuery()->accessCheck(FALSE); $series_query->condition('type_settings.entity_types.eventseries.*', $event->bundle()); - $series_workflows = $series_query->execute(); + $series_workflows = $series_query->accessCheck(FALSE)->execute(); $series_workflows = array_keys($series_workflows); $series_workflow = reset($series_workflows); $instance_query = $this->entityTypeManager->getStorage('workflow')->getQuery()->accessCheck(FALSE); $instance_query->condition('type_settings.entity_types.eventinstance.*', $instance->bundle()); - $instance_workflows = $instance_query->execute(); + $instance_workflows = $instance_query->accessCheck(FALSE)->execute(); $instance_workflows = array_keys($instance_workflows); $instance_workflow = reset($instance_workflows); diff --git a/src/EventInstanceListBuilder.php b/src/EventInstanceListBuilder.php index 599a2d498c450c0c0c95eb98d06ea18c7b92bfbd..4df170b575d35e167e4fef7e48168e3e92c11c23 100644 --- a/src/EventInstanceListBuilder.php +++ b/src/EventInstanceListBuilder.php @@ -142,14 +142,14 @@ class EventInstanceListBuilder extends EntityListBuilder { * {@inheritdoc} */ protected function getEntityIds() { - $query = $this->getStorage()->getQuery() + $query = $this->getStorage()->getQuery()->accessCheck(TRUE) ->sort('date__value', 'ASC'); // Only add the pager if a limit is specified. if ($this->limit) { $query->pager($this->limit); } - return $query->execute(); + return $query->accessCheck(FALSE)->execute(); } } diff --git a/src/EventInstanceStorage.php b/src/EventInstanceStorage.php index ed1ae7c32fa8651ecab95b4b488c434384d506ee..76e3586f8c5ab89d39c7c78f0dd370b6fcbeb5f5 100644 --- a/src/EventInstanceStorage.php +++ b/src/EventInstanceStorage.php @@ -51,6 +51,7 @@ class EventInstanceStorage extends SqlContentEntityStorage implements EventInsta return $this->database->update('eventinstance_revision') ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED]) ->condition('langcode', $language->getId()) + ->accessCheck(FALSE) ->execute(); } diff --git a/src/EventSeriesListBuilder.php b/src/EventSeriesListBuilder.php index fc59888fdf60f7f3c1e8f3b5c176dd506aa80048..0eb011aba6d9782abe99ea837cba0ff58ad24c8c 100644 --- a/src/EventSeriesListBuilder.php +++ b/src/EventSeriesListBuilder.php @@ -149,14 +149,14 @@ class EventSeriesListBuilder extends EntityListBuilder { * {@inheritdoc} */ protected function getEntityIds() { - $query = $this->getStorage()->getQuery() + $query = $this->getStorage()->getQuery()->accessCheck(TRUE) ->sort('changed', 'DESC'); // Only add the pager if a limit is specified. if ($this->limit) { $query->pager($this->limit); } - return $query->execute(); + return $query->accessCheck(FALSE)->execute(); } } diff --git a/src/EventSeriesStorage.php b/src/EventSeriesStorage.php index 858a69e308522f2de6374e22ff3a23aa55049661..852c6c49046d4a6b40052f62253a3c6dfc78fb78 100644 --- a/src/EventSeriesStorage.php +++ b/src/EventSeriesStorage.php @@ -51,6 +51,7 @@ class EventSeriesStorage extends SqlContentEntityStorage implements EventSeriesS return $this->database->update('eventseries_revision') ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED]) ->condition('langcode', $language->getId()) + ->accessCheck(FALSE) ->execute(); } diff --git a/src/EventSubscriber/RecurringEventsAdminRouteSubscriber.php b/src/EventSubscriber/RecurringEventsAdminRouteSubscriber.php index 13a38dc617b9715f28ec7e9f2091682488c78cff..b9334fbf57692c059a07b3d102980782adc30ba5 100644 --- a/src/EventSubscriber/RecurringEventsAdminRouteSubscriber.php +++ b/src/EventSubscriber/RecurringEventsAdminRouteSubscriber.php @@ -69,7 +69,7 @@ class RecurringEventsAdminRouteSubscriber extends RouteSubscriberBase { /** * {@inheritdoc} */ - public static function getSubscribedEvents() : array { + public static function getSubscribedEvents(): array { $events = parent::getSubscribedEvents(); $events[ConfigEvents::SAVE][] = ['onConfigSave', 0]; return $events; diff --git a/src/EventUserTrait.php b/src/EventUserTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..79694531f0347df2656fb347f13d2fb137d735eb --- /dev/null +++ b/src/EventUserTrait.php @@ -0,0 +1,94 @@ +<?php + +namespace Drupal\recurring_events; + +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\user\UserInterface; + +trait EventUserTrait { + + /** + * Returns an array of base field definitions for entity owners. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * The entity type to add the uid field to. + * + * @return \Drupal\Core\Field\BaseFieldDefinition[] + * An array of base field definitions. + * + * @throws \Drupal\Core\Entity\Exception\UnsupportedEntityTypeDefinitionException + * Thrown when the entity type does not have an "uid" entity key. + */ + public static function ownerBaseFieldDefinitions(EntityTypeInterface $entity_type) { + if (!$entity_type->hasKey('uid')) { + throw new UnsupportedEntityTypeDefinitionException('The entity type ' . $entity_type->id() . ' does not have a "uid" entity key.'); + } + + return [ + $entity_type->getKey('uid') => BaseFieldDefinition::create('entity_reference') + ->setLabel(new TranslatableMarkup('User ID')) + ->setSetting('target_type', 'user') + ->setTranslatable($entity_type->isTranslatable()) + ->setDefaultValueCallback(static::class . '::getDefaultEntityOwner'), + ]; + } + + /** + * {@inheritdoc} + */ + public function getOwnerId() { + return $this->getEntityKey('uid'); + } + + /** + * {@inheritdoc} + */ + public function setOwnerId($uid) { + $key = $this->getEntityType()->getKey('uid'); + $this->set($key, $uid); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getOwner() { + $key = $this->getEntityType()->getKey('uid'); + return $this->get($key)->entity; + } + + /** + * {@inheritdoc} + */ + public function setOwner(UserInterface $account) { + $key = $this->getEntityType()->getKey('uid'); + $this->set($key, $account); + + return $this; + } + + /** + * Default value callback for 'uid' base field. + * + * @return mixed + * A default value for the uid field. + */ + public static function getDefaultEntityOwner() { + return \Drupal::currentUser()->id(); + } + + /** + * Backwards compatibility for getCurrentUserId(). + * + * @return mixed + * A default value for the uid field. + */ + public static function getCurrentUserId() { + return static::getDefaultEntityOwner(); + } + +} diff --git a/src/Form/OrphanedEventInstanceForm.php b/src/Form/OrphanedEventInstanceForm.php index 70175b457aa1299ac267181340c2f7d10990af22..83508c60b091f4d48eead4c09f8333aeeb5f956b 100644 --- a/src/Form/OrphanedEventInstanceForm.php +++ b/src/Form/OrphanedEventInstanceForm.php @@ -156,6 +156,7 @@ class OrphanedEventInstanceForm extends FormBase { ->fields('efd', ['id']); $query->leftJoin('eventseries', 'es', 'efd.eventseries_id = es.id'); $instances = $query->condition('es.id', NULL, 'IS NULL') + ->accessCheck(FALSE) ->execute() ->fetchCol(); diff --git a/src/Plugin/ComputedField/EventInstances.php b/src/Plugin/ComputedField/EventInstances.php index e5efd463c44ad2e4134839680cf86e09fe524a90..769412bc3770c45848d654f2c88bb680c4a026eb 100644 --- a/src/Plugin/ComputedField/EventInstances.php +++ b/src/Plugin/ComputedField/EventInstances.php @@ -29,7 +29,7 @@ class EventInstances extends EntityReferenceFieldItemList { }); foreach ($instances as $key => $instance) { - $this->list[$key] = $this->createItem($key, $instance); + $this->list[$key] = $this->createItem($key, $instance->getTranslation($this->getLangcode())); } } }