View source
<?php
namespace Drupal\forms_steps\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\forms_steps\FormsStepsInterface;
use Drupal\forms_steps\Step;
use Drupal\forms_steps\ProgressStep;
use Drupal\Core\Url;
class FormsSteps extends ConfigEntityBase implements FormsStepsInterface {
const ENTITY_TYPE = 'forms_steps';
public $id = NULL;
protected $label;
protected $description = '';
protected $progress_steps_links_saved_only = '';
protected $progress_steps_links_saved_only_next = '';
protected $redirection_policy = '';
protected $redirection_target = '';
protected $steps = [];
protected $progress_steps = [];
public function getDescription() {
return $this->description;
}
public function getProgressStepsLinksSavedOnly() {
return $this->progress_steps_links_saved_only;
}
public function getProgressStepsLinksSavedOnlyNext() {
return $this->progress_steps_links_saved_only_next;
}
public function getRedirectionPolicy() {
return $this->redirection_policy;
}
public function getRedirectionTarget() {
return $this->redirection_target;
}
public function addStep($step_id, $label, $entityType, $entityBundle, $formMode, $url) {
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;
}
public function addProgressStep($progress_step_id, $label, array $routes, $link, array $link_visibility) {
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;
}
public function hasStep($step_id) {
return isset($this->steps[$step_id]);
}
public function hasProgressStep($progress_step_id) {
return isset($this->progress_steps[$progress_step_id]);
}
public function getNextStep(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;
}
}
public function getPreviousStep(Step $step) {
$previousStep = NULL;
$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;
}
public function getStepRoute(Step $step) {
$route = 'forms_steps.' . $this->id . '.' . $step
->id();
return $route;
}
public function getNextStepRoute(Step $step) {
$nextRoute = NULL;
$nextStep = $this
->getNextStep($step);
if ($nextStep) {
$nextRoute = 'forms_steps.' . $this->id . '.' . $nextStep
->id();
}
return $nextRoute;
}
public function getPreviousStepRoute(Step $step) {
$previousRoute = NULL;
$previousStep = $this
->getPreviousStep($step);
if ($previousStep) {
$previousRoute = 'forms_steps.' . $this->id . '.' . $previousStep
->id();
}
return $previousRoute;
}
public function getSteps(array $step_ids = NULL) {
if ($step_ids === NULL) {
$step_ids = array_keys($this->steps);
}
$steps = array_combine($step_ids, array_map([
$this,
'getStep',
], $step_ids));
if (count($steps) > 1) {
$weights = $labels = [];
foreach ($steps as $id => $step) {
$weights[$id] = $step
->weight();
$labels[$id] = $step
->label();
}
array_multisort($weights, SORT_NUMERIC, SORT_ASC, $labels, SORT_NATURAL, SORT_ASC);
$steps = array_replace($weights, $steps);
}
return $steps;
}
public function getProgressSteps(array $progress_step_ids = NULL) {
if ($progress_step_ids === NULL) {
$progress_step_ids = array_keys($this->progress_steps);
}
$progress_steps = array_combine($progress_step_ids, array_map([
$this,
'getProgressStep',
], $progress_step_ids));
if (count($progress_steps) > 1) {
$weights = $labels = [];
foreach ($progress_steps as $id => $progress_step) {
$weights[$id] = $progress_step
->weight();
$labels[$id] = $progress_step
->label();
}
array_multisort($weights, SORT_NUMERIC, SORT_ASC, $labels, SORT_NATURAL, SORT_ASC);
$progress_steps = array_replace($weights, $progress_steps);
}
return $progress_steps;
}
public function getFirstStep($steps = NULL) {
if ($steps === NULL) {
$steps = $this
->getSteps();
}
return reset($steps);
}
public function getLastStep($steps = NULL) {
if ($steps === NULL) {
$steps = $this
->getSteps();
}
return end($steps);
}
public function getStep($step_id) {
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;
}
public function getProgressStep($progress_step_id) {
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()}'");
}
$progress_step = new ProgressStep($this, $progress_step_id, $this->progress_steps[$progress_step_id]['label'], $this->progress_steps[$progress_step_id]['weight'], isset($this->progress_steps[$progress_step_id]['routes']) ? $this->progress_steps[$progress_step_id]['routes'] : [], isset($this->progress_steps[$progress_step_id]['link']) ? $this->progress_steps[$progress_step_id]['link'] : '', isset($this->progress_steps[$progress_step_id]['link_visibility']) ? $this->progress_steps[$progress_step_id]['link_visibility'] : []);
return $progress_step;
}
public function setStepLabel($step_id, $label) {
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;
}
public function setProgressStepLabel($progress_step_id, $label) {
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;
}
public function setStepWeight($step_id, $weight) {
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;
}
public function setProgressStepWeight($progress_step_id, $weight) {
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;
}
public function setStepEntityBundle($step_id, $entityBundle) {
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;
}
public function setStepUrl($step_id, $url) {
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;
}
public function setStepFormMode($step_id, $formMode) {
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;
}
public function setStepEntityType($step_id, $entity_type) {
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;
}
public function setStepSubmitLabel($step_id, $label) {
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;
}
public function setStepCancelLabel($step_id, $label) {
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;
}
public function setStepCancelRoute($step_id, $route) {
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;
}
public function setStepCancelStep($step_id, Step $step = NULL) {
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;
}
public function setStepCancelStepMode($step_id, $mode) {
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;
}
public function setStepDeleteLabel($step_id, $label) {
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;
}
public function setStepDeleteState($step_id, $state) {
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;
}
public function setProgressStepActiveRoutes($progress_step_id, array $routes) {
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;
}
public function setProgressStepLink($progress_step_id, $link) {
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;
}
public function setProgressStepLinkVisibility($progress_step_id, array $steps) {
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;
}
public function deleteStep($step_id) {
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;
}
public function deleteProgressStep($progress_step_id) {
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;
}
protected function getNextWeight(array $items) {
return array_reduce($items, function ($carry, $item) {
return max($carry, $item['weight'] + 1);
}, 0);
}
public function status() {
return !empty($this->status) && !empty($this->steps);
}
public function setStepPreviousLabel($step_id, $label) {
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;
}
public function setStepPreviousState($step_id, $state) {
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;
}
}