rng-3.x-dev/src/Form/EventTypeForm.php

src/Form/EventTypeForm.php
<?php

namespace Drupal\rng\Form;

use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\rng\RngConfigurationInterface;
use Drupal\rng\EventManagerInterface;
use Drupal\node\Entity\NodeType;
use Drupal\rng\Entity\EventTypeRule;
use Drupal\rng\Entity\RegistrantType;

/**
 * Form controller for event config entities.
 */
class EventTypeForm extends EntityForm {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Bundle Info.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  protected $bundleInfo;

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

  /**
   * The entity display repository.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
   */
  protected $entityDisplayRepository;

  /**
   * The RNG configuration service.
   *
   * @var \Drupal\rng\RngConfigurationInterface
   */
  protected $rngConfiguration;

  /**
   * The RNG event manager.
   *
   * @var \Drupal\rng\EventManagerInterface
   */
  protected $eventManager;

  /**
   * Constructs a EventTypeForm object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity manager.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
   *   The Bundle Info.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler service.
   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
   *   The entity display repository.
   * @param \Drupal\rng\RngConfigurationInterface $rng_configuration
   *   The RNG configuration service.
   * @param \Drupal\rng\EventManagerInterface $event_manager
   *   The RNG event manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info, ModuleHandlerInterface $module_handler, EntityDisplayRepositoryInterface $entity_display_repository, RngConfigurationInterface $rng_configuration, EventManagerInterface $event_manager) {
    $this->entityTypeManager = $entity_type_manager;
    $this->bundleInfo = $bundle_info;
    $this->moduleHandler = $module_handler;
    $this->entityDisplayRepository = $entity_display_repository;
    $this->rngConfiguration = $rng_configuration;
    $this->eventManager = $event_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('entity_type.bundle.info'),
      $container->get('module_handler'),
      $container->get('entity_display.repository'),
      $container->get('rng.configuration'),
      $container->get('rng.event_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);
    /** @var \Drupal\rng\Entity\EventTypeInterface $event_type */
    $event_type = $this->entity;

    if (!$event_type->isNew()) {
      $form['#title'] = $this->t('Edit event type %label configuration', [
        '%label' => $event_type->label(),
      ]);
    }

    if ($event_type->isNew()) {
      $bundle_options = [];
      // Generate a list of fieldable bundles which are not events.
      foreach ($this->entityTypeManager->getDefinitions() as $entity_type) {
        if ($entity_type->entityClassImplements('\Drupal\Core\Entity\ContentEntityInterface')) {
          foreach ($this->bundleInfo->getBundleInfo($entity_type->id()) as $bundle => $bundle_info) {
            if (!$this->eventManager->eventType($entity_type->id(), $bundle)) {
              $bundle_options[(string) $entity_type->getLabel()][$entity_type->id() . '.' . $bundle] = $bundle_info['label'];
            }
          }
        }
      }

      if ($this->moduleHandler->moduleExists('node')) {
        $form['#attached']['library'][] = 'rng/rng.admin';
        $form['entity_type'] = [
          '#type' => 'radios',
          '#options' => NULL,
          '#title' => $this->t('Event entity type'),
          '#required' => TRUE,
          // Kills \Drupal\Core\Render\Element\Radios::processRadios.
          '#process' => [],
        ];
        $form['entity_type']['node']['radio'] = [
          '#type' => 'radio',
          '#title' => $this->t('Create a new content type'),
          '#description' => $this->t('Create a content type to use as an event type.'),
          '#return_value' => "node",
          '#parents' => ['entity_type'],
          '#default_value' => 'node',
        ];

        $form['entity_type']['existing']['radio'] = [
          '#type' => 'radio',
          '#title' => $this->t('Use existing bundle'),
          '#description' => $this->t('Use an existing entity/bundle combination.'),
          '#return_value' => "existing",
          '#parents' => ['entity_type'],
          '#default_value' => '',
        ];

        $form['entity_type']['existing']['container'] = [
          '#type' => 'container',
          '#attributes' => [
            'class' => ['rng-radio-indent'],
          ],
        ];
      }

      $form['entity_type']['existing']['container']['bundle'] = [
        '#type' => 'select',
        '#title' => $this->t('Bundle'),
        '#options' => $bundle_options,
        '#default_value' => $event_type->id(),
        '#disabled' => !$event_type->isNew(),
        '#empty_option' => $bundle_options ? NULL : t('No Bundles Available'),
      ];
    }

    $form['settings'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Settings'),
    ];

    // Mirror permission.
    $form['access']['mirror_update'] = [
      '#group' => 'settings',
      '#type' => 'checkbox',
      '#title' => t('Mirror manage registrations with update permission'),
      '#description' => t('Allow users to <strong>manage registrations</strong> if they have <strong>update</strong> permission on an event entity.'),
      '#default_value' => (($event_type->getEventManageOperation() !== NULL) ? $event_type->getEventManageOperation() : TRUE),
    ];

    // Allow Anonymous Registrants?
    $form['allow_anon_registrants'] = [
      '#group' => 'settings',
      '#type' => 'checkbox',
      '#title' => t('Allow anonymous registrants without saving to other identities?'),
      '#description' => t('Allow editing registrant data as text fields on a registration. Add fields to the registrant type for information you would like to collect.'),
      '#default_value' => $event_type->getAllowAnonRegistrants(),
    ];

    // Auto Sync Registrants.
    $form['auto_sync_registrants'] = [
      '#group' => 'settings',
      '#type' => 'checkbox',
      '#title' => t('Sync matching field data between registrant and registrant identity'),
      '#description' => t('If there are empty fields on either the registrant or an identity, copy data from the other when a registrant is updated. This can streamline views of attendee data.'),
      '#default_value' => $event_type->getAutoSyncRegistrants(),
    ];

    // Auto Attach User Identities.
    $form['auto_attach_users'] = [
      '#group' => 'settings',
      '#type' => 'checkbox',
      '#title' => t('Automatically add user identities to anonymous registrants if email matches'),
      '#description' => t('If an email field in a registrant matches a user account, automatically add the user account as the identity.'),
      '#default_value' => $event_type->getAutoAttachUsers(),
      '#states' => [
        'invisible' => [
          ':input[name="allow_anon_registrants"]' => ['checked' => FALSE],
        ],
      ],
    ];

    // Registrant email field.
    $form['registrant_email_field'] = [
      '#group' => 'settings',
      '#type' => 'textfield',
      '#title' => t('Registrant email field'),
      '#description' => t('Machine name of a field on the registrant to use when looking up a user account.'),
      '#default_value' => $event_type->getRegistrantEmailField(),
      '#states' => [
        'invisible' => [
          ':input[name="auto_attach_users"]' => ['checked' => FALSE],
        ],
      ],
    ];

    // Event date fields.
    $form['event_date_field_start'] = [
      '#group' => 'settings',
      '#type' => 'textfield',
      '#title' => t('Event Start Date field'),
      '#description' => t('Machine name of a field on the event to use as the event start date.'),
      '#default_value' => $event_type->getEventStartDateField(),
    ];
    $form['event_date_field_end'] = [
      '#group' => 'settings',
      '#type' => 'textfield',
      '#title' => t('Event End Date field'),
      '#description' => t('Machine name of a field on the event to use as the event end date. Will be combined into a "friendly" date string on registrations.'),
      '#default_value' => $event_type->getEventEndDateField(),
    ];

    $registrant_types = [];
    foreach (RegistrantType::loadMultiple() as $registrant_type) {
      /** @var \Drupal\rng\Entity\RegistrantTypeInterface $registrant_type */
      $registrant_types[$registrant_type->id()] = $registrant_type->label();
    }

    $form['registrants'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Registrants'),
      '#tree' => TRUE,
    ];

    // Default registrant type.
    $form['registrants']['registrant_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Default registrant type'),
      '#description' => $this->t('Registrant type used for new registrants associated with this event type.'),
      '#required' => TRUE,
      '#options' => $registrant_types,
      '#default_value' => $event_type->getDefaultRegistrantType(),
    ];

    $form['registrants']['registrants'] = [
      '#type' => 'table',
      '#header' => [
        [
          'data' => $this->t('Person type'),
        ],
        [
          'data' => $this->t('Permit inline creation of entities'),
          'class' => ['checkbox'],
        ],
        [
          'data' => $this->t('Form display mode'),
        ],
        [
          'data' => $this->t('Permit referencing existing entities'),
          'class' => ['checkbox'],
        ],
      ],
      '#empty' => $this->t('There are no people types available.'),
    ];

    foreach ($this->rngConfiguration->getIdentityTypes() as $entity_type_id) {
      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
      $bundles = $this->bundleInfo->getBundleInfo($entity_type_id);
      foreach ($bundles as $bundle => $info) {
        $t_args = [
          '@bundle' => $info['label'],
          '@entity_type' => $entity_type->getLabel(),
        ];

        $row = [];
        $row['people_type']['#markup'] = $this->t('@bundle (@entity_type)', $t_args);

        $row['create'] = [
          '#type' => 'checkbox',
          '#title' => $this->t('Permit inline creation of @bundle entities', $t_args),
          '#title_display' => 'invisible',
          '#default_value' => $event_type->canIdentityTypeCreate($entity_type_id, $bundle),
          '#wrapper_attributes' => [
            'class' => ['checkbox'],
          ],
        ];

        $row['entity_form_mode'] = [
          '#type' => 'select',
          '#title' => $this->t('Form display mode used when the entity is created inline.', $t_args),
          '#title_display' => 'invisible',
          '#default_value' => $event_type->getIdentityTypeEntityFormMode($entity_type_id, $bundle),
          '#options' => $this->entityDisplayRepository->getFormModeOptionsByBundle($entity_type_id, $bundle),
        ];

        $row['existing'] = [
          '#type' => 'checkbox',
          '#title' => $this->t('Permit referencing existing @bundle entities', $t_args),
          '#title_display' => 'invisible',
          '#default_value' => $event_type->canIdentityTypeReference($entity_type_id, $bundle),
          '#wrapper_attributes' => [
            'class' => ['checkbox'],
          ],
        ];

        $row_key = "$entity_type_id:$bundle";
        $form['registrants']['registrants'][$row_key] = $row;
      }
    }

    // Check if user people type is enabled, then apply some special handling.
    if (isset($form['registrants']['registrants']['user:user'])) {
      // Blacklist user creation. It does not work because it is special.
      $form['registrants']['registrants']['user:user']['create']['#access'] = FALSE;

      // Auto check existing references for users.
      if ($event_type->isNew()) {
        $form['registrants']['registrants']['user:user']['existing']['#default_value'] = TRUE;
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_state->cleanValues();
    $this->entity = $this->buildEntity($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\rng\Entity\EventTypeInterface $event_type */
    $event_type = $this->getEntity();

    if ($event_type->isNew()) {
      if ($this->moduleHandler->moduleExists('node') && ($form_state->getValue('entity_type') == 'node')) {
        $node_type = $this->createContentType('Event');
        $t_args = [
          '%label' => $node_type->label(),
          ':url' => $node_type->toUrl()->toString(),
        ];
        $this->messenger()->addMessage(t('The content type <a href=":url">%label</a> has been added.', $t_args));
        $event_type->setEventEntityTypeId($node_type->getEntityType()->getBundleOf());
        $event_type->setEventBundle($node_type->id());
      }
      else {
        $bundle = explode('.', $form_state->getValue('bundle'));
        $event_type->setEventEntityTypeId($bundle[0]);
        $event_type->setEventBundle($bundle[1]);
      }
    }

    foreach ($form_state->getValue(['registrants', 'registrants']) as $row_key => $row) {
      [$entity_type, $bundle] = explode(':', $row_key);
      $event_type->setIdentityTypeCreate($entity_type, $bundle, !empty($row['create']));
      $event_type->setIdentityTypeReference($entity_type, $bundle, !empty($row['existing']));
      $event_type->setIdentityTypeEntityFormMode($entity_type, $bundle, $row['entity_form_mode']);
    }

    $event_type->setDefaultRegistrantType($form_state->getValue([
      'registrants',
      'registrant_type',
    ]));
    // Set to the access operation for event.
    $op = $form_state->getValue('mirror_update') ? 'update' : '';
    $event_type->setEventManageOperation($op)
      ->setAllowAnonRegistrants($form_state->getValue('allow_anon_registrants'))
      ->setAutoSyncRegistrants($form_state->getValue('auto_sync_registrants'))
      ->setAutoAttachUsers($form_state->getValue('auto_attach_users'))
      ->setRegistrantEmailField($form_state->getValue('registrant_email_field'))
      ->setEventStartDateField($form_state->getValue('event_date_field_start'))
      ->setEventEndDateField($form_state->getValue('event_date_field_end'));

    $status = $event_type->save();

    // Create default rules.
    if ($status == SAVED_NEW) {
      $this->createDefaultRules($event_type->getEventEntityTypeId(), $event_type->getEventBundle());
    }

    $t_args = ['%label' => $event_type->id()];
    if ($status == SAVED_NEW) {
      $message = $this->t('%label event type added.', $t_args);
    }
    else {
      $message = $this->t('%label event type updated.', $t_args);
    }
    $context = $t_args + ['link' => $event_type->toLink($this->t('Edit'), 'edit-form')->toString()];

    $this->messenger()->addMessage($message);
    $this->logger('rng')->notice($message->getUntranslatedString(), $context);

    // Return to the overview form.
    $form_state->setRedirect('rng.rng_event_type.overview');
  }

  /**
   * Creates a content type.
   *
   * Attempts to create a content type with ID $prefix, $prefix_1, $prefix_2...
   *
   * @param string $prefix
   *   A string prefix for the node type ID.
   *
   * @return \Drupal\node\NodeTypeInterface
   *   A node type entity.
   */
  protected function createContentType($prefix) {
    // Generate a unique ID.
    $i = 0;
    $separator = '_';
    $id = $prefix;
    while (NodeType::load(mb_strtolower($id))) {
      $i++;
      $id = $prefix . $separator . $i;
    }

    $node_type = NodeType::create([
      'type' => mb_strtolower($id),
      'name' => $id,
    ]);
    $node_type->save();
    return $node_type;
  }

  /**
   * Create default rules for an event type.
   *
   * @param string $entity_type_id
   *   An entity type ID.
   * @param string $bundle
   *   A bundle ID.
   */
  public static function createDefaultRules($entity_type_id, $bundle) {
    // User Role.
    /** @var \Drupal\rng\Entity\EventTypeRuleInterface $rule */
    $rule = EventTypeRule::create([
      'trigger' => 'rng_event.register',
      'entity_type' => $entity_type_id,
      'bundle' => $bundle,
      'machine_name' => 'user_role',
    ]);
    $rule->setCondition('role', [
      'id' => 'rng_user_role',
      'roles' => [],
    ]);
    $rule->setAction('registration_operations', [
      'id' => 'registration_operations',
      'configuration' => [
        'operations' => [
          'create' => TRUE,
        ],
      ],
    ]);
    $rule->save();

    // Registrant.
    $rule = EventTypeRule::create([
      'trigger' => 'rng_event.register',
      'entity_type' => $entity_type_id,
      'bundle' => $bundle,
      'machine_name' => 'registrant',
    ]);
    $rule->setCondition('identity', [
      'id' => 'rng_registration_identity',
    ]);
    $rule->setAction('registration_operations', [
      'id' => 'registration_operations',
      'configuration' => [
        'operations' => [
          'view' => TRUE,
          'update' => TRUE,
        ],
      ],
    ]);
    $rule->save();

    // Event managers.
    $rule = EventTypeRule::create([
      'trigger' => 'rng_event.register',
      'entity_type' => $entity_type_id,
      'bundle' => $bundle,
      'machine_name' => 'event_manager',
    ]);
    $rule->setCondition('operation', [
      'id' => 'rng_event_operation',
      'operations' => ['manage event' => TRUE],
    ]);
    $rule->setAction('registration_operations', [
      'id' => 'registration_operations',
      'configuration' => [
        'operations' => [
          'create' => TRUE,
          'view' => TRUE,
          'update' => TRUE,
          'delete' => TRUE,
        ],
      ],
    ]);
    $rule->save();
  }

}

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

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