forms_steps-8.x-1.4/src/Entity/FormsSteps.php

src/Entity/FormsSteps.php
<?php

declare(strict_types=1);

namespace Drupal\forms_steps\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\forms_steps\FormsStepsInterface;
use Drupal\forms_steps\ProgressStepInterface;
use Drupal\forms_steps\Step;
use Drupal\forms_steps\ProgressStep;
use Drupal\Core\Url;
use Drupal\forms_steps\StepInterface;

/**
 * FormsSteps configuration entity to persistently store configuration.
 *
 * @ConfigEntityType(
 *   id = "forms_steps",
 *   label = @Translation("FormsSteps"),
 *   handlers = {
 *     "list_builder" = "Drupal\forms_steps\Builder\FormsStepsListBuilder",
 *     "form" = {
 *        "add" = "\Drupal\forms_steps\Form\FormsStepsAddForm",
 *        "edit" = "\Drupal\forms_steps\Form\FormsStepsEditForm",
 *        "delete" = "\Drupal\Core\Entity\EntityDeleteForm",
 *        "add-step" = "\Drupal\forms_steps\Form\FormsStepsStepAddForm",
 *        "edit-step" = "\Drupal\forms_steps\Form\FormsStepsStepEditForm",
 *        "delete-step" = "\Drupal\Core\Entity\EntityDeleteForm",
 *        "add-progress-step" = "\Drupal\forms_steps\Form\FormsStepsProgressStepAddForm",
 *        "edit-progress-step" = "\Drupal\forms_steps\Form\FormsStepsProgressStepEditForm",
 *        "delete-progress-step" = "\Drupal\Core\Entity\EntityDeleteForm",
 *      }
 *   },
 *   admin_permission = "administer forms_steps",
 *   config_prefix = "forms_steps",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *     "uuid" = "uuid",
 *   },
 *   config_export = {
 *     "id",
 *     "label",
 *     "description",
 *     "progress_steps_links_saved_only",
 *     "progress_steps_links_saved_only_next",
 *     "redirection_policy",
 *     "redirection_target",
 *     "steps",
 *     "progress_steps",
 *   },
 *   links = {
 *     "collection" = "/admin/config/workflow/forms_steps",
 *     "edit-form" = "/admin/config/workflow/forms_steps/edit/{forms_steps}",
 *     "delete-form" =
 *   "/admin/config/workflow/forms_steps/delete/{forms_steps}",
 *     "add-form" = "/admin/config/workflow/forms_steps/add",
 *     "add-step-form" =
 *   "/admin/config/workflow/forms_steps/{forms_steps}/add_step",
 *     "add-progress-step-form" =
 *   "/admin/config/workflow/forms_steps/{forms_steps}/add_progress_step",
 *   }
 * )
 */
class FormsSteps extends ConfigEntityBase implements FormsStepsInterface {

  /**
 * Entity type id. */
  const ENTITY_TYPE = 'forms_steps';

  /**
   * The unique ID of the Forms Steps.
   *
   * @var string
   */
  public string $id = '';

  /**
   * The label of the FormsSteps.
   *
   * @var string
   */
  protected string $label;

  /**
   * The description of the FormsSteps, which is used only in the interface.
   *
   * @var string
   */
  protected string $description = '';

  /**
   * The progress_steps_links_saved_only setting of the FormsSteps.
   *
   * @var string
   */
  protected string $progress_steps_links_saved_only = '';


  /**
   * The progress_steps_links_saved_only_next setting of the FormsSteps.
   *
   * @var string
   */
  protected string $progress_steps_links_saved_only_next = '';

  /**
   * The redirection policy of the FormsSteps.
   *
   * @var string
   */
  protected string $redirection_policy = '';

  /**
   * The redirection target of the FormsSteps.
   *
   * @var string
   */
  protected string $redirection_target = '';

  /**
   * The ordered FormsSteps steps.
   *
   * Steps array. The array is numerically indexed by the step id and contains
   * arrays with the following structure:
   *   - weight: weight of the step
   *   - label: label of the step
   *   - form_id: form id of the step
   *   - form_mode: form mode of the form of the step
   *   - url: url of the step.
   *
   * @var array
   */
  protected array $steps = [];

  /**
   * The ordered FormsSteps progress steps.
   *
   * Progress steps array. The array is numerically indexed by the progress step
   * id and contains arrays with the following structure:
   *   - weight: weight of the progress step
   *   - label: label of the progress step
   *   - form_id: form id of the progress step
   *   - routes: an array of the routes for which the progress step is active
   *   - link: the link of the progress step.
   *
   * @var array
   */
  protected array $progress_steps = [];

  /**
   * Returns the description.
   */
  public function getDescription(): string {
    return $this->description;
  }

  /**
   * Returns the Progress steps links saved only setting.
   */
  public function getProgressStepsLinksSavedOnly(): string {
    return $this->progress_steps_links_saved_only;
  }

  /**
   * Returns the Progress steps links saved only next setting.
   */
  public function getProgressStepsLinksSavedOnlyNext(): string {
    return $this->progress_steps_links_saved_only_next;
  }

  /**
   * Returns the redirection policy.
   */
  public function getRedirectionPolicy(): string {
    return $this->redirection_policy;
  }

  /**
   * Returns the redirection target.
   */
  public function getRedirectionTarget(): string {
    return $this->redirection_target;
  }

  /**
   * {@inheritdoc}
   */
  public function addStep(string $step_id, string $label, string $entityType, string $entityBundle, string $formMode, string $url): FormsStepsInterface {
    if (isset($this->Steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' already exists in the forms steps '{$this->id()}'"
      );
    }
    if (preg_match('/[^a-z0-9_]+/', $step_id)) {
      throw new \InvalidArgumentException(
        "The Step ID '$step_id' must contain only lowercase letters, numbers, and underscores"
      );
    }
    $this->steps[$step_id] = [
      'label' => $label,
      'weight' => $this->getNextWeight($this->steps),
      'entity_type' => $entityType,
      'entity_bundle' => $entityBundle,
      'form_mode' => $formMode,
      'url' => $url,
    ];
    ksort($this->steps);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addProgressStep(string $progress_step_id, string $label, array $routes, string $link, array $link_visibility):FormsStepsInterface {
    if (isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The Progress Step '$progress_step_id' already exists in the forms steps '{$this->id()}'"
      );
    }
    if (preg_match('/[^a-z0-9_]+/', $progress_step_id)) {
      throw new \InvalidArgumentException(
        "The Progress Step ID '$progress_step_id' must contain only lowercase letters, numbers, and underscores"
      );
    }
    $this->progress_steps[$progress_step_id] = [
      'label' => $label,
      'weight' => $this->getNextWeight($this->progress_steps),
      'routes' => $routes,
      'link' => $link,
      'link_visibility' => $link_visibility,
    ];
    ksort($this->progress_steps);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function hasStep(string $step_id): bool {
    return isset($this->steps[$step_id]);
  }

  /**
   * {@inheritdoc}
   */
  public function hasProgressStep(string $progress_step_id): bool {
    return isset($this->progress_steps[$progress_step_id]);
  }

  /**
   * {@inheritdoc}
   */
  public function getNextStep(Step $step): ?Step {
    $nextStep = NULL;

    foreach ($this->getSteps() as $current_step) {
      if (is_null($nextStep)) {
        $nextStep = $current_step;
      }
      else {
        if ($nextStep->weight() < $current_step->weight()) {
          $nextStep = $current_step;

          if ($nextStep->weight() > $step->weight()) {
            break;
          }
        }
      }
    }

    if (is_null($nextStep)) {
      return NULL;
    }
    else {
      return $nextStep;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getPreviousStep(Step $step): ?Step {
    $previousStep = NULL;

    // Reverse the order of the array.
    $stepsReversed = array_reverse($this->getSteps());
    $stepsIterator = new \ArrayIterator($stepsReversed);

    while ($stepsIterator->valid()) {
      if (strcmp($stepsIterator->current()->id(), $step->id()) == 0) {
        $stepsIterator->next();
        $previousStep = $stepsIterator->current();

        break;
      }
      else {
        $stepsIterator->next();
      }
    }

    return $previousStep;
  }

  /**
   * {@inheritdoc}
   */
  public function getStepRoute(Step $step): ?string {
    return 'forms_steps.' . $this->id . '.' . $step->id();
  }

  /**
   * {@inheritdoc}
   */
  public function getNextStepRoute(Step $step): ?string {
    $nextRoute = NULL;

    $nextStep = $this->getNextStep($step);

    if ($nextStep) {
      $nextRoute = 'forms_steps.' . $this->id . '.' . $nextStep->id();
    }

    return $nextRoute;
  }

  /**
   * Returns the previous step route.
   *
   * @param \Drupal\forms_steps\Step $step
   *   Current Step.
   *
   * @return null|string
   *   Returns the previous route.
   */
  public function getPreviousStepRoute(Step $step): ?string {
    $previousRoute = NULL;

    $previousStep = $this->getPreviousStep($step);

    if ($previousStep) {
      $previousRoute = 'forms_steps.' . $this->id . '.' . $previousStep->id();
    }

    return $previousRoute;
  }

  /**
   * {@inheritdoc}
   */
  public function getSteps(array $step_ids = NULL): array {
    if ($step_ids === NULL) {
      $step_ids = array_keys($this->steps);
    }
    /** @var \Drupal\forms_steps\StepInterface[] $steps */
    $steps = array_combine($step_ids, array_map([$this, 'getStep'], $step_ids));
    $this->sortElements($steps);
    return $steps;
  }

  /**
   * {@inheritdoc}
   */
  public function getProgressSteps(array $progress_step_ids = NULL): array {
    if ($progress_step_ids === NULL) {
      $progress_step_ids = array_keys($this->progress_steps);
    }

    /** @var \Drupal\forms_steps\ProgressStepInterface[] $progress_steps */
    $progress_steps = array_combine(
      $progress_step_ids,
      array_map([$this, 'getProgressStep'],
        $progress_step_ids)
    );
    $this->sortElements($progress_steps);
    return $progress_steps;
  }

  /**
   * Sort steps or progress steps elements by weight and label.
   *
   * @param array $elements
   *   The steps or progress steps elements.
   */
  protected function sortElements(array &$elements) {
    if (count($elements) > 1) {
      // Sort Steps by weight and then label.
      $weights = $labels = [];
      foreach ($elements as $id => $element) {
        $weights[$id] = $element->weight();
        $labels[$id] = $element->label();
      }
      array_multisort(
        $weights, SORT_NUMERIC, SORT_ASC,
        $labels, SORT_NATURAL, SORT_ASC
      );
      $elements = array_replace($weights, $elements);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getFirstStep(string $steps = NULL): StepInterface {
    if ($steps === NULL) {
      $steps = $this->getSteps();
    }
    return reset($steps);

  }

  /**
   * {@inheritdoc}
   */
  public function getLastStep(string $steps = NULL): StepInterface {
    if ($steps === NULL) {
      $steps = $this->getSteps();
    }
    return end($steps);

  }

  /**
   * {@inheritdoc}
   */
  public function getStep(string $step_id): StepInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $step = new Step(
      $this,
      $step_id,
      $this->steps[$step_id]['label'],
      $this->steps[$step_id]['weight'],
      $this->steps[$step_id]['entity_type'],
      $this->steps[$step_id]['entity_bundle'],
      $this->steps[$step_id]['form_mode'],
      $this->steps[$step_id]['url']
    );

    if (isset($this->steps[$step_id]['cancelStepMode'])) {
      $step->setCancelStepMode($this->steps[$step_id]['cancelStepMode']);
    }
    if (isset($this->steps[$step_id]['cancelRoute'])) {
      $step->setCancelRoute($this->steps[$step_id]['cancelRoute']);
    }
    if (isset($this->steps[$step_id]['submitLabel'])) {
      $step->setSubmitLabel($this->steps[$step_id]['submitLabel']);
    }
    if (isset($this->steps[$step_id]['cancelLabel'])) {
      $step->setCancelLabel($this->steps[$step_id]['cancelLabel']);
    }
    if (isset($this->steps[$step_id]['cancelStep'])) {
      $step->setCancelStep($this->getStep($this->steps[$step_id]['cancelStep']));
    }
    if (isset($this->steps[$step_id]['hideDelete'])) {
      $step->setHideDelete($this->steps[$step_id]['hideDelete']);
    }
    if (isset($this->steps[$step_id]['deleteLabel']) &&
      (!isset($this->steps[$step_id]['hideDelete']) || !$this->steps[$step_id]['hideDelete'])
    ) {
      $step->setDeleteLabel($this->steps[$step_id]['deleteLabel']);
    }
    if (isset($this->steps[$step_id]['displayPrevious'])) {
      $step->setDisplayPrevious($this->steps[$step_id]['displayPrevious']);
    }
    if (isset($this->steps[$step_id]['previousLabel'])) {
      $step->setPreviousLabel($this->steps[$step_id]['previousLabel']);
    }

    return $step;
  }

  /**
   * {@inheritdoc}
   */
  public function getProgressStep(string $progress_step_id): ProgressStepInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    return new ProgressStep(
      $this,
      $progress_step_id,
      $this->progress_steps[$progress_step_id]['label'],
      $this->progress_steps[$progress_step_id]['weight'],
      $this->progress_steps[$progress_step_id]['routes'] ?? [],
      $this->progress_steps[$progress_step_id]['link'] ?? '',
      $this->progress_steps[$progress_step_id]['link_visibility'] ?? []
    );
  }

  /**
   * {@inheritdoc}
   */
  public function setStepLabel(string $step_id, string $label): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['label'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setProgressStepLabel(string $progress_step_id, string $label): FormsStepsInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->progress_steps[$progress_step_id]['label'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepWeight(string $step_id, int $weight): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['weight'] = $weight;
    return $this;
  }

  /**
   * Set the weight for a progress step.
   */
  public function setProgressStepWeight($progress_step_id, $weight): FormsSteps {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->progress_steps[$progress_step_id]['weight'] = $weight;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepEntityBundle(string $step_id, string $entityBundle): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['entity_bundle'] = $entityBundle;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepUrl(string $step_id, string $url): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['url'] = '';
    if ('/' != $url[0]) {
      $url = '/' . $url;
    }
    if (!empty(Url::fromUri("internal:$url"))) {
      $this->steps[$step_id]['url'] = $url;
    }
    else {
      throw new \InvalidArgumentException(
        "The Url Step '$url' is not accessible"
      );
    }

    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepFormMode(string $step_id, string $formMode): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['form_mode'] = $formMode;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepEntityType(string $step_id, string $entity_type): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['entity_type'] = $entity_type;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepSubmitLabel(string $step_id, string $label): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['submitLabel'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepCancelLabel(string $step_id, string $label): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['cancelLabel'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepCancelRoute(string $step_id, string $route): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['cancelRoute'] = $route;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepCancelStep(string $step_id, Step $step): FormsStepsInterface {
    if (!$step) {
      return $this;
    }
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['cancelStep'] = $step;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepCancelStepMode(string $step_id, string $mode): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['cancelStepMode'] = $mode;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepDeleteLabel(string $step_id, $label): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['deleteLabel'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepDeleteState(string $step_id, bool $state): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['hideDelete'] = $state;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setProgressStepActiveRoutes(string $progress_step_id, array $routes): FormsStepsInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->progress_steps[$progress_step_id]['routes'] = $routes;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setProgressStepLink(string $progress_step_id, string $link): FormsStepsInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->progress_steps[$progress_step_id]['link'] = $link;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setProgressStepLinkVisibility(string $progress_step_id, array $steps): FormsStepsInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->progress_steps[$progress_step_id]['link_visibility'] = $steps;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteStep(string $step_id): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    if (count($this->steps) === 1) {
      throw new \InvalidArgumentException(
        "The step '$step_id' can not be deleted from forms steps '{$this->id()}' as it is the only Step"
      );
    }

    unset($this->steps[$step_id]);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function deleteProgressStep(string $progress_step_id): FormsStepsInterface {
    if (!isset($this->progress_steps[$progress_step_id])) {
      throw new \InvalidArgumentException(
        "The progress step '$progress_step_id' does not exist in forms steps '{$this->id()}'"
      );
    }

    unset($this->progress_steps[$progress_step_id]);
    return $this;
  }

  /**
   * Gets the weight for a new step or progress step.
   *
   * @param array $items
   *   An array of steps where each item has a
   *   'weight' key with a numeric value.
   *
   * @return int
   *   The weight for a step in the array so that it has the highest weight.
   */
  protected function getNextWeight(array $items): int {
    return array_reduce($items, function ($carry, $item) {
      return max($carry, $item['weight'] + 1);
    }, 0);
  }

  /**
   * {@inheritdoc}
   */
  public function status(): bool {
    // In order for a forms_steps to be usable it must have at least one step.
    return !empty($this->status) && !empty($this->steps);
  }

  /**
   * {@inheritdoc}
   */
  public function setStepPreviousLabel(string $step_id, $label): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['previousLabel'] = $label;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setStepPreviousState(string $step_id, bool $state): FormsStepsInterface {
    if (!isset($this->steps[$step_id])) {
      throw new \InvalidArgumentException(
        "The Step '$step_id' does not exist in forms steps '{$this->id()}'"
      );
    }
    $this->steps[$step_id]['displayPrevious'] = $state;
    return $this;
  }

}

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

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