diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..053a60b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,28 @@ +CHANGELOG +========= + +0.1.3 +----- + * [Breaking Changes] Refactor action handler execution + + *Before* + ```php + $flow->handleAction(); + ``` + + *After* + ```php + $flow->getClickedActionButton()->handle(); + ``` + +0.1.2 +----- + * Fixed profile collector + +0.1.1 +----- + * Add more tests + +0.1.0 +----- + * Initial Proposal diff --git a/src/Form/Flow/ActionButton.php b/src/Form/Flow/ActionButton.php index 70e6064..1dc6d13 100644 --- a/src/Form/Flow/ActionButton.php +++ b/src/Form/Flow/ActionButton.php @@ -2,6 +2,7 @@ namespace Yceruto\FormFlowBundle\Form\Flow; +use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\SubmitButton; /** @@ -10,6 +11,7 @@ class ActionButton extends SubmitButton implements ActionButtonInterface { private mixed $data = null; + private bool $handled = false; public function submit(array|string|null $submittedData, bool $clearMissing = true): static { @@ -41,6 +43,27 @@ public function getHandler(): callable return $this->getConfig()->getOption('handler'); } + public function isHandled(): bool + { + return $this->handled; + } + + public function handle(): void + { + /** @var FormInterface $form */ + $form = $this->getParent(); + $data = $form->getData(); + + while ($form && !$form instanceof FormFlowInterface) { + $form = $form->getParent(); + } + + $handler = $this->getHandler(); + $handler($data, $this, $form); + + $this->handled = true; + } + public function isResetAction(): bool { return 'reset' === $this->getAction(); diff --git a/src/Form/Flow/ActionButtonInterface.php b/src/Form/Flow/ActionButtonInterface.php index 5206398..1997594 100644 --- a/src/Form/Flow/ActionButtonInterface.php +++ b/src/Form/Flow/ActionButtonInterface.php @@ -17,6 +17,16 @@ public function getAction(): string; */ public function getHandler(): callable; + /** + * Checks if the callable handler was already called. + */ + public function isHandled(): bool; + + /** + * Executes the callable handler. + */ + public function handle(): void; + /** * Checks if the button's action is 'reset'. */ diff --git a/src/Form/Flow/FormFlow.php b/src/Form/Flow/FormFlow.php index 57c56ad..7a2ec8e 100644 --- a/src/Form/Flow/FormFlow.php +++ b/src/Form/Flow/FormFlow.php @@ -4,7 +4,6 @@ use Symfony\Component\Form\Exception\AlreadySubmittedException; use Symfony\Component\Form\Exception\InvalidArgumentException; -use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Form; @@ -19,7 +18,6 @@ class FormFlow extends Form implements FormFlowInterface { private ?ActionButtonInterface $clickedActionButton = null; private bool $finished = false; - private bool $handled = false; public function __construct( private readonly FormFlowConfigInterface $config, @@ -61,20 +59,6 @@ public function submit(mixed $submittedData, bool $clearMissing = true): static return $this; } - public function handleAction(): void - { - if (!$this->clickedActionButton) { - throw new LogicException('No action button was clicked.'); - } - - /** @var FormInterface $form */ - $form = $this->clickedActionButton->getParent(); - $handler = $this->clickedActionButton->getHandler(); - $handler($form->getData(), $this->clickedActionButton, $this); - - $this->handled = true; - } - public function reset(): void { $this->config->getDataStorage()->clear(); @@ -112,8 +96,8 @@ public function getStepForm(): static return $this; } - if ($this->clickedActionButton && !$this->handled) { - $this->handleAction(); + if ($this->clickedActionButton && !$this->clickedActionButton->isHandled()) { + $this->clickedActionButton->handle(); } if (!$this->isValid()) { diff --git a/src/Form/Flow/FormFlowBuilder.php b/src/Form/Flow/FormFlowBuilder.php index 7ef4f1e..ebdd1d0 100644 --- a/src/Form/Flow/FormFlowBuilder.php +++ b/src/Form/Flow/FormFlowBuilder.php @@ -94,7 +94,13 @@ public function setInitialOptions(array $options): static public function getInitialStep(): string { - return $this->stepAccessor->getStep($this->initialOptions['data']) ?: (string) key($this->steps); + $defaultStep = (string) key($this->steps); + + if (!isset($this->initialOptions['data'])) { + return $defaultStep; + } + + return (string) $this->stepAccessor->getStep($this->initialOptions['data'], $defaultStep); } public function getInitialOptions(): array diff --git a/src/Form/Flow/FormFlowInterface.php b/src/Form/Flow/FormFlowInterface.php index 06a79a9..3f9d69a 100644 --- a/src/Form/Flow/FormFlowInterface.php +++ b/src/Form/Flow/FormFlowInterface.php @@ -13,13 +13,6 @@ interface FormFlowInterface extends FormInterface */ public function getClickedActionButton(): ?ActionButtonInterface; - /** - * Executes the handler associated with the clicked action button. - * - * @throws LogicException If no action button was clicked - */ - public function handleAction(): void; - /** * Resets the flow by clearing stored data and setting the cursor to the initial step. */