diff --git a/modules/recurring_events_registration/recurring_events_registration.module b/modules/recurring_events_registration/recurring_events_registration.module index aecfde229dd7156b4b3e8a6081248e399aa7b3b2..48b196f4f23239bdaa7c15485fa52d9e61e423d1 100644 --- a/modules/recurring_events_registration/recurring_events_registration.module +++ b/modules/recurring_events_registration/recurring_events_registration.module @@ -13,7 +13,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\recurring_events_registration\Entity\Registrant; use Drupal\recurring_events\Entity\EventSeries; use Drupal\recurring_events\Entity\EventInstance; -use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; /** @@ -154,7 +153,7 @@ function recurring_events_registration_recurring_events_registration_notificatio /** * Implements hook_recurring_events_save_pre_instances_deletion(). */ -function recurring_events_registration_recurring_events_save_pre_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) { +function recurring_events_registration_recurring_events_save_pre_instances_deletion(EventSeries $event_series) { $registration_creation_service = \Drupal::service('recurring_events_registration.creation_service'); $registration_creation_service->setEventSeries($event_series); diff --git a/recurring_events.api.php b/recurring_events.api.php index 272f86d437d73661262f6889f0c31664d468cfc8..cc9bccd9bd77a206648241123e05273b186aa52a 100644 --- a/recurring_events.api.php +++ b/recurring_events.api.php @@ -117,10 +117,10 @@ function hook_recurring_events_inheritance_class_alter(&$class, $field) { * * @param Drupal\recurring_events\Entity\EventSeries $event_series * The eventseries being altered. - * @param Drupal\Core\Form\FormStateInterface $form_state - * The form state of an updated event series entity. + * @param Drupal\recurring_events\Entity\EventSeries $original + * The original, unaltered eventseries. */ -function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) { +function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_series, EventSeries $original) { } /** @@ -133,10 +133,10 @@ function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_se * * @param Drupal\recurring_events\Entity\EventSeries $event_series * The eventseries being altered. - * @param Drupal\Core\Form\FormStateInterface $form_state - * The form state of an updated event series entity. + * @param Drupal\recurring_events\Entity\EventSeries $original + * The original, unaltered eventseries. */ -function hook_recurring_events_save_post_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) { +function hook_recurring_events_save_post_instances_deletion(EventSeries $event_series, EventSeries $original) { } /** diff --git a/recurring_events.module b/recurring_events.module index 82094d5e4c593e90524a6a899fb2ed054cdd394b..8524af3c5ea34a0bf19df0bebb490bfe45356cb3 100644 --- a/recurring_events.module +++ b/recurring_events.module @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Render\Element; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Form\FormStateInterface; /** * Implements hook_help(). @@ -146,3 +147,84 @@ function template_preprocess_eventseries(array &$variables) { $variables['content'][$key] = $variables['elements'][$key]; } } + +/** + * Implements hook_ENTITY_TYPE_presave(). + */ +function recurring_events_eventseries_presave(EntityInterface $entity) { + $original = $entity->original; + $creation_service = \Drupal::service('recurring_events.event_creation_service'); + + // If the eventseries is being published, or created for the first time then + // there may be date recurrence changes that need to be converted into new + // eventinstance entities. + if ($entity->isPublished() || $entity->isNew()) { + if ($entity->isDefaultTranslation()) { + $creation_service->saveEvent($entity, $original); + } + } +} + +/** + * Implements hook_ENTITY_TYPE_insert(). + */ +function recurring_events_eventseries_insert(EntityInterface $entity) { + // When we initially create the eventseries we actually create the instances + // before the eventseries gets saved for the first time, so we have no ID for + // the series at that point. Now that the eventseries is properly saved we can + // go and set the eventseries_id on the eventinstances. + $instances = $entity->event_instances->referencedEntities(); + if (!empty($instances)) { + foreach ($instances as $instance) { + if (empty($instance->eventseries_id->value)) { + $instance->set('eventseries_id', $entity->id()); + $instance->setNewRevision(FALSE); + $instance->save(); + } + } + } +} + +/** + * Implements hook_form_FORM_ID_alter(). + */ +function recurring_events_form_content_moderation_entity_moderation_form_alter(&$form, FormStateInterface $form_state) { + $entity = $form_state->get('entity'); + if ($entity->getEntityTypeId() === 'eventseries') { + $original = \Drupal::entityTypeManager()->getStorage('eventseries')->load($entity->id()); + $creation_service = \Drupal::service('recurring_events.event_creation_service'); + if ($creation_service->checkForOriginalRecurConfigChanges($entity, $original)) { + $diff_array = $creation_service->buildDiffArray($original, NULL, $entity); + if (!empty($diff_array)) { + $form['diff'] = [ + '#type' => 'container', + '#weight' => -99, + ]; + + $form['diff']['diff_title'] = [ + '#type' => '#markup', + '#prefix' => '<h2>', + '#markup' => t('Revision Date Changes'), + '#suffix' => '</h2>', + ]; + + $form['diff']['diff_message'] = [ + '#type' => '#markup', + '#prefix' => '<p>', + '#markup' => t('Recurrence configuration has been changed in this revision, as a result if you choose to publish this revision all instances will be removed and recreated. This action cannot be undone.'), + '#suffix' => '</p>', + ]; + + $form['diff']['table'] = [ + '#type' => 'table', + '#header' => [ + t('Data'), + t('Stored'), + t('Overridden'), + ], + '#rows' => $diff_array, + ]; + } + } + } +} diff --git a/src/Controller/EventInstanceController.php b/src/Controller/EventInstanceController.php index 8d151fdf96b81413737a1a243ae9f31e0f97db7e..45bcdb0c86f925c336fbbba740e254597dc113e6 100644 --- a/src/Controller/EventInstanceController.php +++ b/src/Controller/EventInstanceController.php @@ -191,7 +191,7 @@ class EventInstanceController extends ControllerBase implements ContainerInjecti '#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => [ - 'date' => $link, + 'date' => $link->toString(), 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->getRevisionLogMessage(), '#allowed_tags' => Xss::getHtmlTagList()], ], diff --git a/src/Controller/EventSeriesController.php b/src/Controller/EventSeriesController.php index 6a23f202d1bf47d8183f39a8e63d0bb848dd2ede..1b495b185809d6b23fcc15ec918c0b985e1802de 100644 --- a/src/Controller/EventSeriesController.php +++ b/src/Controller/EventSeriesController.php @@ -168,7 +168,7 @@ class EventSeriesController extends ControllerBase implements ContainerInjection '#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => [ - 'date' => $link, + 'date' => $link->toString(), 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->getRevisionLogMessage(), '#allowed_tags' => Xss::getHtmlTagList()], ], diff --git a/src/Entity/EventInstance.php b/src/Entity/EventInstance.php index 5c085037bd6e6e626eae0872d54ff66e414b25d9..b000dd9a3493aed7ce86ac36f732db61e5df18db 100644 --- a/src/Entity/EventInstance.php +++ b/src/Entity/EventInstance.php @@ -254,6 +254,21 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface return $this; } + /** + * {@inheritdoc} + */ + public function getRevisionCreationTime() { + return $this->revision_timestamp->value; + } + + /** + * {@inheritdoc} + */ + public function setRevisionCreationTime($timestamp) { + $this->revision_timestamp->value = $timestamp; + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/Entity/EventSeries.php b/src/Entity/EventSeries.php index e9ac8857fff47a9fe4880f5ccc00b67c1027b9da..2b810deb150d71285580fc654aa8bcad486f0acd 100644 --- a/src/Entity/EventSeries.php +++ b/src/Entity/EventSeries.php @@ -253,6 +253,21 @@ class EventSeries extends EditorialContentEntityBase implements EventInterface { return $this; } + /** + * {@inheritdoc} + */ + public function getRevisionCreationTime() { + return $this->revision_timestamp->value; + } + + /** + * {@inheritdoc} + */ + public function setRevisionCreationTime($timestamp) { + $this->revision_timestamp->value = $timestamp; + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/EventCreationService.php b/src/EventCreationService.php index 503567369de4f766c13275b3803973eccead3b00..6d8061e4bb88c8a7ecdefa8af89f30022406b510 100644 --- a/src/EventCreationService.php +++ b/src/EventCreationService.php @@ -280,16 +280,29 @@ class EventCreationService { * @param Drupal\recurring_events\Entity\EventSeries $event * The stored event series entity. * @param Drupal\Core\Form\FormStateInterface $form_state - * The form state of an updated event series entity. + * (Optional) The form state of an updated event series entity. + * @param Drupal\recurring_events\Entity\EventSeries $edited + * (Optional) The edited event series entity. * * @return array * An array of differences. */ - public function buildDiffArray(EventSeries $event, FormStateInterface $form_state) { + public function buildDiffArray(EventSeries $event, FormStateInterface $form_state = NULL, EventSeries $edited = NULL) { $diff = []; $entity_config = $this->convertEntityConfigToArray($event); - $form_config = $this->convertFormConfigToArray($form_state); + $form_config = []; + + if (!is_null($form_state)) { + $form_config = $this->convertFormConfigToArray($form_state); + } + if (!is_null($edited)) { + $form_config = $this->convertEntityConfigToArray($edited); + } + + if (empty($form_config)) { + return $diff; + } if ($entity_config['type'] !== $form_config['type']) { $diff['type'] = [ @@ -414,25 +427,25 @@ class EventCreationService { * * @param Drupal\recurring_events\Entity\EventSeries $event * The stored event series entity. - * @param Drupal\Core\Form\FormStateInterface $form_state - * The form state of an updated event series entity. * @param Drupal\recurring_events\Entity\EventSeries $original * The original, unsaved event series entity. */ - public function saveEvent(EventSeries $event, FormStateInterface $form_state, EventSeries $original = NULL) { - // We only need a revision if this is an existing entity. + public function saveEvent(EventSeries $event, EventSeries $original = NULL) { + $update_event_id = FALSE; + + // If this is a brand new series, then we don't have an ID for it yet to + // save against the instances. So we need to defer that part 'til later. We + // also want to always create instances if this is a brand new series. if ($event->isNew()) { $create_instances = TRUE; - // We have to save the event series first so we can use the ID to store - // against the event instances we create. - $event->save(); + $update_event_id = TRUE; } else { // If there are date differences, we need to clear out the instances. - $create_instances = $this->checkForFormRecurConfigChanges($original, $form_state); + $create_instances = $this->checkForOriginalRecurConfigChanges($event, $original); if ($create_instances) { // Allow other modules to react prior to the deletion of all instances. - \Drupal::moduleHandler()->invokeAll('recurring_events_save_pre_instances_deletion', [$event, $form_state]); + \Drupal::moduleHandler()->invokeAll('recurring_events_save_pre_instances_deletion', [$event, $original]); // Find all the instances and delete them. $instances = $event->event_instances->referencedEntities(); @@ -454,13 +467,13 @@ class EventCreationService { } // Allow other modules to react after the deletion of all instances. - \Drupal::moduleHandler()->invokeAll('recurring_events_save_post_instances_deletion', [$event, $form_state]); + \Drupal::moduleHandler()->invokeAll('recurring_events_save_post_instances_deletion', [$event, $original]); } } // Only create instances if date changes have been made or the event is new. if ($create_instances) { - $this->createInstances($event, $form_state); + $this->createInstances($event); } } @@ -469,11 +482,9 @@ class EventCreationService { * * @param Drupal\recurring_events\Entity\EventSeries $event * The stored event series entity. - * @param Drupal\Core\Form\FormStateInterface $form_state - * The form state of an updated event series entity. */ - public function createInstances(EventSeries $event, FormStateInterface $form_state) { - $form_data = $this->convertFormConfigToArray($form_state); + public function createInstances(EventSeries $event) { + $form_data = $this->convertEntityConfigToArray($event); $event_instances = []; $timezone = new \DateTimeZone(drupal_get_user_timezone()); @@ -634,7 +645,7 @@ class EventCreationService { // If the start date is after the end date then we have an invalid range so // just return nothing. - if ($start > $end) { + if ($start->getTimestamp() > $end->getTimestamp()) { return $dates; } @@ -646,7 +657,7 @@ class EventCreationService { // Loop through a week at a time, storing the date in the array to return // until the end date is surpassed. - while ($start <= $end) { + while ($start->getTimestamp() <= $end->getTimestamp()) { // If we do not clone here we end up modifying the value of start in // the array and get some funky dates returned. $dates[] = clone $start; @@ -682,7 +693,7 @@ class EventCreationService { // If the start date is after the end date then we have an invalid range so // just return nothing. - if ($start > $end) { + if ($start->getTimestamp() > $end->getTimestamp()) { return $dates; } @@ -718,7 +729,7 @@ class EventCreationService { // Loop through each month checking to see if the day of the month is a // valid day, until the end date has been surpassed. - while ($start <= $end) { + while ($start->getTimestamp() <= $end->getTimestamp()) { // If we do not clone here we end up modifying the value of start in // the array and get some funky dates returned. $dates[] = clone $start; @@ -787,7 +798,7 @@ class EventCreationService { // If the start date is after the end date then we have an invalid range so // just return nothing. - if ($start > $end_date) { + if ($start->getTimestamp() > $end_date->getTimestamp()) { return $dates; } @@ -802,7 +813,7 @@ class EventCreationService { // Loop through a week at a time, storing the date in the array to return // until the end date is surpassed. - while ($start <= $end_date) { + while ($start->getTimestamp() <= $end_date->getTimestamp()) { // If we do not clone here we end up modifying the value of start in // the array and get some funky dates returned. $dates[] = clone $start; diff --git a/src/EventInstanceStorage.php b/src/EventInstanceStorage.php index 37abf099ae872d8909b64aeae5a2b4c27254d39a..ed1ae7c32fa8651ecab95b4b488c434384d506ee 100644 --- a/src/EventInstanceStorage.php +++ b/src/EventInstanceStorage.php @@ -5,7 +5,6 @@ namespace Drupal\recurring_events; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\recurring_events\EventInterface; /** * Defines the storage handler class for eventinstance entities. diff --git a/src/EventInstanceStorageInterface.php b/src/EventInstanceStorageInterface.php index 2a6e586eb79c79ff081c5d0532ba910878e302df..021ca2c75a0529b5da1ee1724501815dc6962d07 100644 --- a/src/EventInstanceStorageInterface.php +++ b/src/EventInstanceStorageInterface.php @@ -5,7 +5,6 @@ namespace Drupal\recurring_events; use Drupal\Core\Entity\ContentEntityStorageInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\recurring_events\EventInterface; /** * Defines the storage handler class for eventinstance entities. diff --git a/src/EventInstanceTranslationHandler.php b/src/EventInstanceTranslationHandler.php index ce1f6810b35bb2718a8c9bc2f88ffe74be110598..6f3e8a4a8d6cfa86e79151ae3c6876d14fb1246b 100644 --- a/src/EventInstanceTranslationHandler.php +++ b/src/EventInstanceTranslationHandler.php @@ -10,5 +10,4 @@ use Drupal\content_translation\ContentTranslationHandler; class EventInstanceTranslationHandler extends ContentTranslationHandler { // Override here the needed methods from ContentTranslationHandler. - } diff --git a/src/EventSeriesStorage.php b/src/EventSeriesStorage.php index 76f60bb8b84095917075263e2da7edf866588c68..858a69e308522f2de6374e22ff3a23aa55049661 100644 --- a/src/EventSeriesStorage.php +++ b/src/EventSeriesStorage.php @@ -5,7 +5,6 @@ namespace Drupal\recurring_events; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\recurring_events\EventInterface; /** * Defines the storage handler class for eventseries entities. diff --git a/src/EventSeriesStorageInterface.php b/src/EventSeriesStorageInterface.php index 4d05919b53c120b3acf721f7a6190ed3a7d9b228..f4f1d568346446fdc98d043522450b1d75c38abf 100644 --- a/src/EventSeriesStorageInterface.php +++ b/src/EventSeriesStorageInterface.php @@ -5,7 +5,6 @@ namespace Drupal\recurring_events; use Drupal\Core\Entity\ContentEntityStorageInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\recurring_events\EventInterface; /** * Defines the storage handler class for eventseries entities. diff --git a/src/EventSeriesTranslationHandler.php b/src/EventSeriesTranslationHandler.php index f2e1d8170abb419afee9b6296e29f617305006b0..c6aa726251e80c740d6bd0742d8b958d6e34cf34 100644 --- a/src/EventSeriesTranslationHandler.php +++ b/src/EventSeriesTranslationHandler.php @@ -10,5 +10,4 @@ use Drupal\content_translation\ContentTranslationHandler; class EventSeriesTranslationHandler extends ContentTranslationHandler { // Override here the needed methods from ContentTranslationHandler. - } diff --git a/src/FieldInheritanceHtmlRouteProvider.php b/src/FieldInheritanceHtmlRouteProvider.php index dd0fba9ebdcad329ca3195296f0d61a88ca6942b..52dd17146dda740ad59c8a7e8201c5fa69a9b24a 100644 --- a/src/FieldInheritanceHtmlRouteProvider.php +++ b/src/FieldInheritanceHtmlRouteProvider.php @@ -4,7 +4,6 @@ namespace Drupal\recurring_events; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider; -use Symfony\Component\Routing\Route; /** * Provides routes for Field inheritance entities. @@ -21,7 +20,6 @@ class FieldInheritanceHtmlRouteProvider extends AdminHtmlRouteProvider { $collection = parent::getRoutes($entity_type); // Provide your custom entity routes here. - return $collection; } diff --git a/src/Form/EventSeriesForm.php b/src/Form/EventSeriesForm.php index 23701789162f2e84b9a8cb11da1b511662772f95..d15764393c95619ae6cd1b33ff8a44d36d7675d3 100644 --- a/src/Form/EventSeriesForm.php +++ b/src/Form/EventSeriesForm.php @@ -231,13 +231,11 @@ class EventSeriesForm extends ContentEntityForm { } if ($entity->isDefaultTranslation()) { - $this->creationService->saveEvent($entity, $form_state, $original); $this->messenger->addStatus($this->t('Successfully saved the %name event series', [ '%name' => $entity->title->value, ])); } else { - $this->messenger->addStatus($this->t('@language translation of the @type %label has been saved.', [ '@language' => $entity->language()->getName(), '@type' => 'Event ',