You are here

class FormModesSubscriber in Form mode manager 8

Same name and namespace in other branches
  1. 8.2 src/Routing/EventSubscriber/FormModesSubscriber.php \Drupal\form_mode_manager\Routing\EventSubscriber\FormModesSubscriber

Subscriber for form_mode_manager routes.

Hierarchy

Expanded class hierarchy of FormModesSubscriber

1 string reference to 'FormModesSubscriber'
form_mode_manager.services.yml in ./form_mode_manager.services.yml
form_mode_manager.services.yml
1 service uses FormModesSubscriber
form_mode_manager.route_subscriber in ./form_mode_manager.services.yml
Drupal\form_mode_manager\Routing\EventSubscriber\FormModesSubscriber

File

src/Routing/EventSubscriber/FormModesSubscriber.php, line 19

Namespace

Drupal\form_mode_manager\Routing\EventSubscriber
View source
class FormModesSubscriber extends RouteSubscriberBase {
  use StringTranslationTrait;

  /**
   * The Regex pattern to contextualize process by route path.
   *
   * @var string
   */
  const ROUTE_PATH_CONTEXT_REGEX = '/^.*?\\/edit[^$]*/';

  /**
   * The Regex pattern to contextualize process by route path.
   *
   * @var string
   */
  const FORM_MODE_DEFAULT_CONTROLLER = '\\Drupal\\form_mode_manager\\Controller\\EntityFormModeController';

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

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

  /**
   * The entity display repository.
   *
   * @var \Drupal\form_mode_manager\FormModeManagerInterface
   */
  protected $formModeManager;

  /**
   * The Routes Manager Plugin.
   *
   * @var \Drupal\form_mode_manager\EntityRoutingMapManager
   */
  protected $entityRoutingMap;

  /**
   * Constructs a new RouteSubscriber object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity type manager.
   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
   *   The entity display repository.
   * @param \Drupal\form_mode_manager\FormModeManagerInterface $form_mode_manager
   *   The form mode manager.
   * @param \Drupal\form_mode_manager\EntityRoutingMapManager $plugin_routes_manager
   *   Plugin EntityRoutingMap to retrieve entity form operation routes.
   */
  public function __construct(EntityTypeManagerInterface $entity_manager, EntityDisplayRepositoryInterface $entity_display_repository, FormModeManagerInterface $form_mode_manager, EntityRoutingMapManager $plugin_routes_manager) {
    $this->entityTypeManager = $entity_manager;
    $this->entityDisplayRepository = $entity_display_repository;
    $this->formModeManager = $form_mode_manager;
    $this->entityRoutingMap = $plugin_routes_manager;
  }

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    $form_modes_definitions = $this->formModeManager
      ->getAllFormModesDefinitions();
    unset($form_modes_definitions['user']);
    foreach ($form_modes_definitions as $entity_type_id => $form_modes) {
      $entity_type = $this->entityTypeManager
        ->getDefinition($entity_type_id);
      $this
        ->addFormModesRoutes($collection, $entity_type, $form_modes);
    }
  }

  /**
   * Generate all operations routes for entities.
   *
   * @param \Symfony\Component\Routing\RouteCollection $collection
   *   The route collection to retrieve parent entity routes.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param array $form_modes
   *   All form-modes available for specified entity_type_id.
   */
  protected function addFormModesRoutes(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_modes) {
    foreach ($form_modes as $form_mode) {
      $this
        ->setFormModeCollection($collection, $entity_type, $form_mode, 'admin_add');
      $this
        ->setFormModeCollection($collection, $entity_type, $form_mode, 'add_form');
      $this
        ->setFormModeCollection($collection, $entity_type, $form_mode, 'edit_form');
      $this
        ->setAddPageCollection($collection, $entity_type, $form_mode);
    }
  }

  /**
   * Create a route per form_mode for given operation form.
   *
   * @param \Symfony\Component\Routing\RouteCollection $collection
   *   The route collection to retrieve parent entity routes.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param array $form_mode
   *   A form-mode for specified entity_type_id.
   * @param string $operation
   *   The entity operation name.
   */
  public function setFormModeCollection(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode, $operation) {

    /** @var \Drupal\form_mode_manager\EntityRoutingMapBase $entity_operation_mapping */
    $entity_operation_mapping = $this->entityRoutingMap
      ->createInstance($entity_type
      ->id(), [
      'entityTypeId' => $entity_type
        ->id(),
    ]);
    if ($entity_operation_mapping
      ->getOperation($operation) && ($route = $this
      ->getFormModeRoute($collection, $entity_type, $form_mode, $operation))) {
      $form_mode_name = $this->formModeManager
        ->getFormModeMachineName($form_mode['id']);
      $collection
        ->add($entity_operation_mapping
        ->getOperation($operation) . ".{$form_mode_name}", $route);
    }
  }

  /**
   * Set one add_page route per form_mode for compatible entities.
   *
   * @param \Symfony\Component\Routing\RouteCollection $collection
   *   The route collection to retrieve parent entity routes.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param array $form_mode
   *   A form-mode for specified entity_type_id.
   *
   * @todo Make this configurable.
   */
  public function setAddPageCollection(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode) {
    $form_mode_name = $this->formModeManager
      ->getFormModeMachineName($form_mode['id']);
    if ($route = $this
      ->getFormModeListPageRoute($entity_type, $form_mode)) {
      $collection
        ->add("form_mode_manager.{$entity_type->id()}.add_page.{$form_mode_name}", $route);
    }
  }

  /**
   * Generate route to Form Mode Manager `add-list` route.
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition. Useful when a single class is,
   *   used for multiple, possibly dynamic entity types.
   * @param array $form_mode
   *   An associative array represent a DisplayForm entity.
   *
   * @return \Symfony\Component\Routing\Route|null
   *   The generated route, if available.
   */
  public function getFormModeListPageRoute(EntityTypeInterface $entity_type, array $form_mode) {
    $route = NULL;
    $entity_type_id = $entity_type
      ->id();
    $entity_type_bundle_id = $entity_type
      ->getBundleEntityType();
    $bundle_entity_type_id = !empty($entity_type_bundle_id) ? $entity_type_bundle_id : $entity_type_id;
    $has_active_mode = $this->formModeManager
      ->hasActiveFormMode($entity_type_id, $this->formModeManager
      ->getFormModeMachineName($form_mode['id']));
    if ($has_active_mode) {
      $route = new Route("/{$entity_type_id}/add-list/{$this->formModeManager->getFormModeMachineName($form_mode['id'])}");
      $route
        ->addDefaults([
        '_controller' => static::FORM_MODE_DEFAULT_CONTROLLER . '::addPage',
        '_title' => $this
          ->t('Add @entity_type', [
          '@entity_type' => $entity_type
            ->getLabel(),
        ])
          ->render(),
        'form_mode_name' => $this->formModeManager
          ->getFormModeMachineName($form_mode['id']),
      ])
        ->addRequirements([
        '_permission' => "use {$form_mode['id']} form mode",
      ])
        ->setOptions([
        '_form_mode_manager_entity_type_id' => $entity_type_id,
        '_form_mode_manager_bundle_entity_type_id' => $bundle_entity_type_id,
        '_admin_route' => TRUE,
      ]);
      $this
        ->userListEnhancements($route, $entity_type
        ->id());
    }
    return $route;
  }

  /**
   * Get the Form Mode Manager route for given operation.
   *
   * @param \Symfony\Component\Routing\RouteCollection $collection
   *   The route collection to retrieve parent entity routes.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param array $form_mode
   *   The form mode info.
   * @param string $operation
   *   The entity operation name.
   *
   * @return \Symfony\Component\Routing\Route|null
   *   The generated route, if available.
   */
  public function getFormModeRoute(RouteCollection $collection, EntityTypeInterface $entity_type, array $form_mode, $operation) {
    $entity_type_id = $entity_type
      ->id();
    $has_active_mode = $this->formModeManager
      ->hasActiveFormMode($entity_type_id, $this->formModeManager
      ->getFormModeMachineName($form_mode['id']));

    /** @var \Drupal\form_mode_manager\EntityRoutingMapBase $entity_operation_mapping */
    $entity_operation_mapping = $this->entityRoutingMap
      ->createInstance($entity_type_id, [
      'entityTypeId' => $entity_type_id,
    ]);
    if ($has_active_mode && ($entity_edit_route = $collection
      ->get($entity_operation_mapping
      ->getOperation($operation)))) {
      return $this
        ->setRoutes($entity_edit_route, $entity_type, $form_mode);
    }
    return NULL;
  }

  /**
   * Set a specific callback for Edit context of User entity.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route object of entity.
   * @param string $entity_type_id
   *   The ID of the entity type.
   */
  public function userListEnhancements(Route $route, $entity_type_id) {
    if ('user' !== $entity_type_id) {
      return;
    }
    $route
      ->setDefault('_controller', '\\Drupal\\form_mode_manager\\Controller\\UserFormModeController::entityAdd')
      ->setDefault('_title_callback', '\\Drupal\\form_mode_manager\\Controller\\UserFormModeController::addPageTitle');
  }

  /**
   * Set Form Mode Manager routes based on parent entity routes.
   *
   * @param \Symfony\Component\Routing\Route $parent_route
   *   The route object of entity.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   * @param array $form_mode
   *   The form mode info.
   *
   * @return \Symfony\Component\Routing\Route
   *   Form Mode Manager route to be added on entity collection.
   */
  private function setRoutes(Route $parent_route, EntityTypeInterface $entity_type, array $form_mode) {
    $route_defaults = NestedArray::mergeDeep($parent_route
      ->getDefaults(), $this
      ->getFormModeRouteDefaults($parent_route, $form_mode));
    $roue_options = NestedArray::mergeDeep($parent_route
      ->getOptions(), $this
      ->getFormModeRouteOptions($form_mode, $entity_type));
    $route_requirements = NestedArray::mergeDeep($parent_route
      ->getRequirements(), $this
      ->getFormModeRouteRequirements($form_mode));
    $route = new Route("{$parent_route->getPath()}/{$this->formModeManager->getFormModeMachineName($form_mode['id'])}");
    $route
      ->addDefaults($route_defaults)
      ->setOptions($roue_options)
      ->addRequirements($route_requirements);
    return $route;
  }

  /**
   * Evaluate if current context is edit.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route object of entity.
   *
   * @return bool
   *   True if current route context is edit or False if not.
   */
  public static function isEditRoute(Route $route) {
    return (bool) preg_match_all(self::ROUTE_PATH_CONTEXT_REGEX, $route
      ->getPath(), $matches, PREG_SET_ORDER, 0);
  }

  /**
   * Get defaults parameters nedeed to build Form Mode Manager routes.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route object of entity.
   * @param array $form_mode
   *   The form mode info.
   *
   * @return array
   *   Array contain defaults routes parameters.
   */
  protected function getFormModeRouteDefaults(Route $route, array $form_mode) {
    $route_parameters = [
      '_entity_form' => $form_mode['id'],
      '_controller' => static::FORM_MODE_DEFAULT_CONTROLLER . '::entityAdd',
      '_title_callback' => static::FORM_MODE_DEFAULT_CONTROLLER . '::addPageTitle',
    ];
    if (static::isEditRoute($route)) {
      $route_parameters['_title_callback'] = static::FORM_MODE_DEFAULT_CONTROLLER . '::editPageTitle';
      $route_parameters['_controller'] = static::FORM_MODE_DEFAULT_CONTROLLER . '::entityEdit';
    }
    return $route_parameters;
  }

  /**
   * Get options parameters nedeed to build Form Mode Manager routes.
   *
   * @param array $form_mode
   *   The form mode info.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type definition.
   *
   * @return array
   *   Array contain options routes parameters.
   */
  protected function getFormModeRouteOptions(array $form_mode, EntityTypeInterface $entity_type) {
    $entity_type_id = $entity_type
      ->id();
    $entity_type_bundle_id = $entity_type
      ->getBundleEntityType();
    $bundle_entity_type_id = !empty($entity_type_bundle_id) ? $entity_type_bundle_id : $entity_type_id;
    return [
      '_form_mode_manager_entity_type_id' => $entity_type_id,
      '_form_mode_manager_bundle_entity_type_id' => $bundle_entity_type_id,
      'parameters' => [
        $entity_type_id => [
          'type' => "entity:{$entity_type_id}",
        ],
        'form_mode' => $form_mode + [
          'type' => NULL,
        ],
      ],
    ];
  }

  /**
   * Get options requirements nedeed to build Form Mode Manager routes.
   *
   * @param array $form_mode
   *   The form mode info.
   *
   * @return array
   *   Array contain requirements routes parameters.
   */
  protected function getFormModeRouteRequirements(array $form_mode) {
    return [
      '_permission' => "use {$form_mode['id']} form mode",
      '_custom_access' => static::FORM_MODE_DEFAULT_CONTROLLER . '::checkAccess',
    ];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FormModesSubscriber::$entityDisplayRepository protected property The entity display repository.
FormModesSubscriber::$entityRoutingMap protected property The Routes Manager Plugin.
FormModesSubscriber::$entityTypeManager protected property The entity type manager service.
FormModesSubscriber::$formModeManager protected property The entity display repository.
FormModesSubscriber::addFormModesRoutes protected function Generate all operations routes for entities.
FormModesSubscriber::alterRoutes protected function Alters existing routes for a specific collection. Overrides RouteSubscriberBase::alterRoutes 1
FormModesSubscriber::FORM_MODE_DEFAULT_CONTROLLER constant The Regex pattern to contextualize process by route path. 1
FormModesSubscriber::getFormModeListPageRoute public function Generate route to Form Mode Manager `add-list` route.
FormModesSubscriber::getFormModeRoute public function Get the Form Mode Manager route for given operation.
FormModesSubscriber::getFormModeRouteDefaults protected function Get defaults parameters nedeed to build Form Mode Manager routes.
FormModesSubscriber::getFormModeRouteOptions protected function Get options parameters nedeed to build Form Mode Manager routes.
FormModesSubscriber::getFormModeRouteRequirements protected function Get options requirements nedeed to build Form Mode Manager routes.
FormModesSubscriber::isEditRoute public static function Evaluate if current context is edit.
FormModesSubscriber::ROUTE_PATH_CONTEXT_REGEX constant The Regex pattern to contextualize process by route path.
FormModesSubscriber::setAddPageCollection public function Set one add_page route per form_mode for compatible entities.
FormModesSubscriber::setFormModeCollection public function Create a route per form_mode for given operation form.
FormModesSubscriber::setRoutes private function Set Form Mode Manager routes based on parent entity routes.
FormModesSubscriber::userListEnhancements public function Set a specific callback for Edit context of User entity.
FormModesSubscriber::__construct public function Constructs a new RouteSubscriber object.
RouteSubscriberBase::getSubscribedEvents public static function Returns an array of event names this subscriber wants to listen to. 5
RouteSubscriberBase::onAlterRoutes public function Delegates the route altering to self::alterRoutes(). 1
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.