recurring_events-2.0.x-dev/src/Plugin/migrate/destination/EntityEventSeries.php

src/Plugin/migrate/destination/EntityEventSeries.php
<?php

declare(strict_types=1);

namespace Drupal\recurring_events\Plugin\migrate\destination;

use Drupal\migrate\Attribute\MigrateDestination;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
use Drupal\recurring_events\Entity\EventSeries;
use Drupal\recurring_events\Plugin\migrate\process\RecurringDate;
use Drupal\recurring_events\Plugin\migrate\process\RRuleHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * The 'entity:eventseries' destination plugin for Recurring Events.
 *
 * Usage:
 *
 * When importing from a Drupal 7 source, use a config similar to the example
 * below (where 'field_event_datetime' is the name of the source date field).
 *
 * @code
 * destination:
 *   plugin: 'entity:eventseries'
 *   default_bundle: default
 *   source_date_field: field_event_datetime
 *   source_timezone: 'America/New_York'
 * @endcode
 *
 * This will directly convert the source field to populate the recurrence
 * options on the event series.
 *
 * If you are instead importing from a non-Drupal 7 source and want to use the
 * process pipeline to construct the recur_type, recurrence options, and
 * excluded/included dates data, you can use the following config (where 'dates'
 * is a destination field built using the 'recurring_date' process plugin).
 *
 * @code
 * destination:
 *   plugin: 'entity:eventseries'
 *   default_bundle: default
 *   recurring_date_field: dates
 * @endcode
 *
 * This will rename the recurring_date_field to match the recur_type before the
 * destination entity is saved. For example:
 *   - If the recur_type is 'weekly_recurring_date', the recurring_date_field
 *     will be renamed to 'weekly_recurring_date' before saving.
 *   - If the recur_type is 'custom', the recurring_date_field will be renamed
 *     to 'custom_date' before saving.
 *
 * Finally, if you simply want to pass your processed destination fields through
 * without any modification (for example, if you are using recur_type = 'custom'
 * for all imported events and constructing your own 'custom_date' field), use
 * the following config.
 *
 * @code
 * destination:
 *   plugin: 'entity:eventseries'
 *   default_bundle: default
 * @endcode
 *
 * Available configuration keys:
 *   - source_date_field: (optional) When importing from a Drupal 7 source, this
 *     is the name of the source field to use for the date recurrence pattern.
 *   - source_timezone: (optional, but required when using 'source_date_field')
 *     The timezone for the source_date_field data.
 *   - recurring_date_field: (optional) When using the recurring_date process
 *     plugin to construct recurrence pattern data, this is the name of the
 *     destination field that contains that plugin's output. In this case, it is
 *     assumed that a 'recur_type' destination field has also been properly set.
 */
#[MigrateDestination(
  id: "entity:eventseries",
)]
class EntityEventSeries extends EntityContentBase {

  /**
   * Module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, ?MigrationInterface $migration = NULL) {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition, $migration);
    $instance->moduleHandler = $container->get('module_handler');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function import(Row $row, array $old_destination_id_values = []) {
    if (isset($this->configuration['source_date_field'])) {
      $source = $row->getSourceProperty($this->configuration['source_date_field']);
      $this->setRecurringDateValues($source, $this->configuration['source_timezone'], $row);
    }
    elseif (isset($this->configuration['recurring_date_field'])) {
      $recurring_date_field = $row->getDestinationProperty($this->configuration['recurring_date_field']);
      $recur_type = $row->getDestinationProperty('recur_type');
      $this->setRecurringDateField($row, $recur_type, $recurring_date_field);
    }
    return parent::import($row, $old_destination_id_values);
  }

  /**
   * Adds recurrence data to the row in a field that matches the recur_type.
   *
   * @param \Drupal\migrate\Row $row
   *   The current row being imported.
   * @param string $recur_type
   *   The recur_type for the eventseries destination entity.
   * @param array $recurring_date_field
   *   An array containing recurrence field data.
   *
   * @see \Drupal\recurring_events\Plugin\migrate\process\RecurringDate
   */
  private function setRecurringDateField(Row $row, string $recur_type, array $recurring_date_field) {
    $recurring_date_field_name = ($recur_type === 'custom') ? 'custom_date' : $recur_type;
    $row->setDestinationProperty($recurring_date_field_name, $recurring_date_field);
  }

  /**
   * Set destination recurring date values directly on the row.
   *
   * @param array $source
   *   The source date field data.
   * @param string $source_timezone
   *   The timezone for the source dates.
   * @param \Drupal\migrate\Row $row
   *   The current row being imported.
   *
   * @throws \Drupal\migrate\MigrateException
   */
  private function setRecurringDateValues(array $source, string $source_timezone, Row $row) {
    // Set the recur_type.
    $rrule_string = $source[0]['rrule'] ?? NULL;
    $rrule = isset($rrule_string) ? RRuleHelper::parseRule($rrule_string) : [];
    $recur_type = RRuleHelper::getRecurType($rrule);
    $row->setDestinationProperty('recur_type', $recur_type);

    // Set the recurrence options.
    $options = RecurringDate::calculateRecurringDateValues($source, [
      'value_key' => 'value',
      'end_value_key' => 'value2',
      'rrule_key' => 'rrule',
      'default_timezone' => $source_timezone,
    ]);
    $this->setRecurringDateField($row, $recur_type, $options);

    if (!empty($rrule['EXDATE'])) {
      $row->setDestinationProperty('excluded_dates', $rrule['EXDATE']);
    }

    // @todo Fix problem of how to set this in D7 here.
    // if (!empty($rrule['INCDATE'])) {
    // $row->setDestinationProperty('included_dates', $rrule['INCDATE']);
    // }
    // $row->setDestinationProperty('event_registration', ['value' => 0]);
  }

  /**
   * {@inheritdoc}
   */
  public function rollback(array $destination_identifier) {
    $entity = $this->storage->load(reset($destination_identifier));
    if ($entity && $entity instanceof EventSeries) {
      $instances = $entity->event_instances->referencedEntities();
      // Allow other modules to react prior to deleting all instances after a
      // date configuration change.
      $this->moduleHandler->invokeAll('recurring_events_pre_delete_instances', [$entity]);
      // Loop through all instances and remove them.
      foreach ($instances as $instance) {
        $instance->delete();
      }
      // Allow other modules to react after deleting all instances after a date
      // configuration change.
      $this->moduleHandler->invokeAll('recurring_events_post_delete_instances', [$entity]);
    }
    parent::rollback($destination_identifier);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc