forms_steps-8.x-1.4/src/Controller/FormsStepsController.php

src/Controller/FormsStepsController.php
<?php

declare(strict_types=1);

namespace Drupal\forms_steps\Controller;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityDisplayRepository;
use Drupal\forms_steps\Entity\Workflow;
use Drupal\forms_steps\Exception\AccessDeniedException;
use Drupal\forms_steps\Exception\FormsStepsNotFoundException;
use Drupal\user\Access\RegisterAccessCheck;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Main controller for the Forms Steps entities behavior.
 *
 * @package Drupal\forms_steps\Controller
 */
class FormsStepsController extends ControllerBase {

  /**
   * User register access check service.
   *
   * @var \Drupal\user\Access\RegisterAccessCheck
   */
  private RegisterAccessCheck $registerAccessCheck;

  /**
   * Entity display repository service.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepository
   */
  private EntityDisplayRepository $entityDisplayRepository;

  /**
   * Form steps controller construct for dependencies injection.
   */
  public function __construct(
    EntityDisplayRepository $entityDisplayRepository,
    RegisterAccessCheck $registerAccessCheck
  ) {
    $this->entityDisplayRepository = $entityDisplayRepository;
    $this->registerAccessCheck = $registerAccessCheck;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): FormsStepsController {
    return new static(
      $container->get('entity_display.repository'),
      $container->get('access_check.user.register')
    );
  }

  /**
   * Display the step form.
   *
   * @param string $forms_steps
   *   Forms Steps id to display step from.
   * @param mixed $step
   *   Step to display.
   * @param string $instance_id
   *   Instance id of the forms steps ref to load.
   *
   * @return array
   *   Form that match the input parameters.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\forms_steps\Exception\AccessDeniedException
   * @throws \Drupal\forms_steps\Exception\FormsStepsNotFoundException
   */
  public function step(string $forms_steps, $step, string $instance_id = NULL): array {
    return $this->getForm($forms_steps, $step, $instance_id);
  }

  /**
   * Get a form based on the $step and $nid.
   *
   * If $nid is empty or not existing we provide a create form, we edit
   * otherwise.
   *
   * @param string $forms_steps
   *   Forms Steps id to get the form from.
   * @param mixed $step
   *   Step to get the Form from.
   * @param string $instance_id
   *   Instance ID of the forms steps reference to load.
   *
   * @return array
   *   Returns the Form.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\forms_steps\Exception\AccessDeniedException
   * @throws \Drupal\forms_steps\Exception\FormsStepsNotFoundException
   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
   *
   * @todo Do we need to move it in a service?
   */
  public function getForm(string $forms_steps, $step, string $instance_id = ''): array {
    /** @var \Drupal\forms_steps\Entity\FormsSteps $formsSteps */
    $formsSteps = $this->entityTypeManager()
      ->getStorage('forms_steps')
      ->load($forms_steps);

    if (!$formsSteps->hasStep($step)) {
      // @todo Propose a better error management.
      throw new \InvalidArgumentException("The Step '$step' does not exist in forms steps '{$forms_steps}'");
    }

    $step = $formsSteps->getStep($step);

    $entity_key_type = $this->entityTypeManager()
      ->getDefinition($step->entityType())
      ->getKey('bundle');

    // We initialize the entity with its potential last revision.
    $entity = NULL;
    $entities = [];
    if (!is_null($instance_id)) {
      try {
        /** @var \Drupal\forms_steps\Entity\Workflow $entities */
        $entities = $this->entityTypeManager()
          ->getStorage(Workflow::ENTITY_TYPE)
          ->loadByProperties(['instance_id' => $instance_id]);
      }
      catch (\Exception $ex) {
      }
      if ($entities) {
        // We look for the same entity bundle.
        foreach ($entities as $_entity) {
          if (strcmp($_entity->get('entity_type')->value, $step->entityType()) == 0
            && strcmp($_entity->get('bundle')->value, $step->entityBundle()) == 0) {
            // We load the entity.
            $storage = $this->entityTypeManager()->getStorage($_entity->entity_type->value);
            $idKey = $storage->getEntityType()->getKey('id');

            if (!$storage->getEntityType()->isRevisionable()) {
              $revision = NULL;
            }
            else {
              $revision = $storage->getQuery()
                ->accessCheck()
                ->condition($idKey, $_entity->entity_id->value)
                ->latestRevision()
                ->execute();
            }

            if ($revision) {
              $rid = key($revision);
              $entity = $storage->loadRevision($rid);
            }
            else {
              $entity = $storage->load($_entity->entity_id->value);
            }
            break;
          }
        }
      }
    }

    $userRegistrationAccess = FALSE;
    if ($step->entityType() == 'user') {
      $account = User::load($this->currentUser()->id());
      $registrationAccess = $this->registerAccessCheck
        ->access($account);
      $userRegistrationAccess = $registrationAccess->isAllowed();
    }

    // If entity not found, this is a new entity to create.
    if (is_null($entity)) {
      $entity = $this->entityTypeManager()
        ->getStorage($step->entityType())
        ->create([$entity_key_type => $step->entityBundle()]);

      if ($entity) {
        if (!empty($instance_id)) {
          if (count($entities) == 0) {
            // No Forms Steps exists with that UUID - Error.
            throw new FormsStepsNotFoundException(t('No multi-step instance found.')->render());
          }
        }
        else {
          if (
            ($step->entityType() !== 'user' && !$entity->access('create')) ||
            ($step->entityType() === 'user' && !($userRegistrationAccess || $entity->access('create')))
          ) {
            throw new AccessDeniedHttpException();
          }
          elseif ($formsSteps->getFirstStep()->id() != $step->id()) {
            throw new AccessDeniedException(t('First step of the multi-step forms is required.')->render());
          }
        }
      }
    }
    else {
      if (
        ($step->entityType() !== 'user' && !$entity->access('update')) ||
        ($step->entityType() === 'user' && !($entity->access('update')))
      ) {
        throw new AccessDeniedException(t('First step of the multi-step forms is required.')->render());
      }
    }

    $formMode = preg_replace("/^{$step->entityType()}\./", '', $step->formMode());
    try {
      // We load the form.
      $form = $this->entityFormBuilder()
        ->getForm(
          $entity,
          $formMode,
          ['form_steps' => TRUE]
        );
    }
    catch (InvalidPluginDefinitionException $e) {
      $entityTypeId = $entity->getEntityTypeId();
      $formModeOptions = $this->entityDisplayRepository
        ->getFormModeOptions($entityTypeId);

      if (isset($formModeOptions[$formMode])) {
        $this->messenger()->addError(
          t(
            "Site's cache must be cleared after adding new form mode: :formMode on :entityTypeId",
            [':formMode' => $formMode, ':entityTypeId' => $entityTypeId]
          )
        );
      }
      else {
        $this->messenger()->addWarning(t(':message - The form class could not be loaded.', [':message' => $e->getMessage()]));
      }
      throw new NotFoundHttpException();
    }

    // Hiding the button following to the configuration.
    if ($step->hideDelete()) {
      unset($form['actions']['delete']);
    }
    elseif ($step->deleteLabel()) {
      $form['actions']['delete']['#title'] = t($step->deleteLabel());
    }

    // Return the form.
    return $form;
  }

}

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

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