PHP code example of lexal / stepped-form

1. Go to this page and download the library: Download lexal/stepped-form library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

lexal / stepped-form example snippets


    use Lexal\SteppedForm\Step\StepInterface;
    
    final class CustomerStep implements StepInterface
    {
        public function handle(mixed $entity, mixed $data): mixed
        {
            // do some logic here
            
            return $entity; // returns an entity that form will save as step data into the storage
        }
    }
    

    use Lexal\SteppedForm\Form\Builder\FormBuilderInterface;
    use Lexal\SteppedForm\Step\Builder\StepsBuilder;
    use Lexal\SteppedForm\Step\Builder\StepsBuilderInterface;
    use Lexal\SteppedForm\Step\Steps;
    
    final class CustomBuilder implements FormBuilderInterface
    {
        public function __construct(private readonly StepsBuilderInterface $builder)
        {
        }

        public function build(mixed $entity): Steps
        {
            $this->builder->add('customer', new CustomerStep());
            // Some additional steps

            return $this->builder->get();
        }
    }

    $builder = new CustomBuilder(new StepsBuilder(/* StepControlInterface */, /* DataControlInterface */));
    

   use Lexal\SteppedForm\Form\Storage\SessionStorageInterface;
   
   final class SessionStorage implements SessionStorageInterface
   {
       public function get(): ?string
       {
           // return current active session key (from redis, database, session or any other storage)
           return 'main';
       }

       public function put(string $sessionKey): void
       {
           // save current form session key
       }
   }

   $sessionControl = new SessionStorage();
   

    use Lexal\SteppedForm\Form\DataControl;
    use Lexal\SteppedForm\Form\StepControl;
    use Lexal\SteppedForm\Form\Storage\DataStorage;
    use Lexal\SteppedForm\Form\Storage\FormStorage;

    $storage = new FormStorage(new InMemoryStorage(), new InMemorySessionStorage()); // can use any other storage (session, database, redis, etc.)
    $stepControl = new StepControl($storage);
    $dataControl = new DataControl(new DataStorage($storage));
    

    use Lexal\SteppedForm\EventDispatcher\EventDispatcherInterface;
   
    final class EventDispatcher implements EventDispatcherInterface
    {
        public function dispatch(object $event): object
        {
            // dispatch events here

            return $event;
        }
    }

    $dispatcher = new EventDispatcher();
    

    use Lexal\SteppedForm\EntityCopy\SimpleEntityCopy;
    use Lexal\SteppedForm\SteppedForm;

    $form = new SteppedForm(
        $dataControl,
        $stepControl,
        $storage,
        $builder,
        $dispatcher,
        new SimpleEntityCopy(),
    );
    

    /* Starts a new form session */
    $form->start(
        /* entity for initialize a form state */,
        /* unique session key if you need to split different sessions of one form */,
    );

    /* Returns a TemplateDefinition of rendered step */
    $form->render('key');

    /* Handles a step logic and saves a new form state */
    $form->handle('key', /* any submitted data */);

    /* Cancels form session */
    $form->cancel();
    

use Lexal\SteppedForm\Step\RenderStepInterface;
use Lexal\SteppedForm\Step\Steps;
use Lexal\SteppedForm\Step\TemplateDefinition;
    
final class CustomerStep implements RenderStepInterface
{
    public function getTemplateDefinition(mixed $entity, Steps $steps): TemplateDefinition
    {
        return new TemplateDefinition('customer', ['customer' => $entity]);
    }

    public function handle(mixed $entity, mixed $data): mixed
    {
        // do some logic here
        $entity->name = $data['name'];
        $entity->amount = (float)$data['amount'];

        return $entity; // return an entity that the form will save as step data into the storage
    }
}

use Lexal\SteppedForm\Step\StepInterface;
    
final class TaxStep implements StepInterface
{
    private const TAX_PERCENT = 20;

    public function handle(mixed $entity, mixed $data): mixed
    {
        // do some logic here
        $entity->tax = $entity->amount * self::TAX_PERCENT;

        return $entity; // returns an entity that form will save as step data into the storage
    }
}

use Lexal\SteppedForm\Form\Builder\StaticStepsFormBuilder;
use Lexal\SteppedForm\Step\Step;
use Lexal\SteppedForm\Step\Steps;

$steps = new Steps([
    new Step('customer', new CustomerStep()),
    new Step('broker', new BrokerStep()),
    /* some more steps */
]);

$builder = new StaticStepsFormBuilder($steps);

use Lexal\SteppedForm\Form\Builder\FormBuilderInterface;
use Lexal\SteppedForm\Step\Builder\StepsBuilderInterface;

final class CustomBuilder implements FormBuilderInterface
{
    public function __construct(private readonly StepsBuilderInterface $builder)
    {
    }

    public function build(mixed $entity): Steps
    {
        $this->builder->add('customer', new CustomerStep());

        // add step depending on previous user input
        if ($entity->createNewBroker) {
            $this->builder->add('broker', new BrokerStep());
        }

        // Some additional steps

        return $this->builder->get();
    }
}

use Lexal\SteppedForm\Step\RenderStepInterface;
use Lexal\SteppedForm\Step\StepBehaviourInterface;
use Lexal\SteppedForm\Step\Steps;
use Lexal\SteppedForm\Step\TemplateDefinition;

final class CustomerStep implements StepBehaviourInterface
{
    public function getTemplateDefinition(mixed $entity, Steps $steps): TemplateDefinition
    {
        // render
    }

    public function handle(mixed $entity, mixed $data): mixed
    {
        // handle
    }
    
    public function forgetDataAfterCurrent(mixed $entity): bool
    {
        return $entity->code === 'NA'; // remove form data after current only when code equals to 'NA'
    }
}