Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Form Handler Bundle Laravel Package

aygon/form-handler-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require aygon/form-handler-bundle
    

    Enable the bundle in config/bundles.php:

    Aygon\FormHandlerBundle\AygonFormHandlerBundle::class => ['all' => true],
    
  2. First Use Case: Extend a Symfony form type to use the handler:

    use Aygon\FormHandlerBundle\Form\Handler\HandlerInterface;
    use Aygon\FormHandlerBundle\Form\Handler\HandlerTrait;
    
    class MyFormType extends AbstractType
    {
        use HandlerTrait;
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $this->setHandler($builder->getData(), $options['handler']);
            // ... form fields
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'handler' => null, // Inject your handler class
            ]);
        }
    }
    
  3. Create a Handler: Implement HandlerInterface or extend AbstractHandler:

    use Aygon\FormHandlerBundle\Form\Handler\AbstractHandler;
    
    class MyFormHandler extends AbstractHandler
    {
        public function handle($data)
        {
            // Process form data (e.g., save to DB, trigger events)
            return true; // Return false to re-render form with errors
        }
    }
    
  4. Use in Controller:

    $form = $this->createForm(MyFormType::class, $entity, [
        'handler' => new MyFormHandler(),
    ]);
    

Implementation Patterns

Workflows

  1. Decoupled Logic:

    • Move form submission logic out of controllers into dedicated handlers.
    • Example: Separate UserRegistrationHandler for user creation, NewsletterHandler for subscriptions.
  2. Reusable Handlers:

    • Create base handlers for common operations (e.g., EntityHandler for CRUD):
      abstract class EntityHandler extends AbstractHandler
      {
          protected $entityManager;
      
          public function __construct(EntityManagerInterface $em)
          {
              $this->entityManager = $em;
          }
      
          public function handle($entity)
          {
              $this->entityManager->persist($entity);
              $this->entityManager->flush();
          }
      }
      
  3. Validation Integration:

    • Use Symfony’s validator in handlers:
      public function handle($data)
      {
          $errors = $this->validator->validate($data);
          if (count($errors) > 0) {
              return false; // Form will re-render with validation errors
          }
          // Proceed with logic
      }
      
  4. Event Dispatching:

    • Trigger events in handlers for decoupled side effects:
      public function handle($data)
      {
          $event = new FormSubmittedEvent($data);
          $this->eventDispatcher->dispatch($event, FormEvents::SUBMITTED);
      }
      

Integration Tips

  • Dependency Injection: Inject services (e.g., EntityManager, Mailer) into handlers via constructor:

    class ContactHandler extends AbstractHandler
    {
        private $mailer;
    
        public function __construct(\Swift_Mailer $mailer)
        {
            $this->mailer = $mailer;
        }
    }
    
  • Form Events: Attach handlers to form events (e.g., PRE_SUBMIT, POST_SUBMIT) for granular control:

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $data = $event->getData();
        // Pre-process data
    });
    
  • Dynamic Handlers: Use factory services to instantiate handlers dynamically:

    # config/services.yaml
    services:
        App\Form\HandlerFactory:
            arguments:
                - '@service_container'
    

Gotchas and Tips

Pitfalls

  1. Handler Lifecycle:

    • Handlers are instantiated per form submission. Avoid storing state in class properties unless using a service container.
  2. Form Data vs. Entity:

    • Ensure handlers work with both raw form data (on PRE_SUBMIT) and bound entities (on POST_SUBMIT).
  3. Error Handling:

    • Return false from handle() to re-render the form. Use $form->addError() for form-wide errors:
      if (!$this->handle($data)) {
          $form->addError(new FormError('An error occurred.'));
      }
      
  4. Symfony 2.1 Constraint:

    • The bundle targets Symfony 2.1. Test thoroughly if upgrading to newer Symfony versions.

Debugging

  • Log Handler Output: Temporarily log handler results to debug:

    public function handle($data)
    {
        $this->logger->debug('Handler data:', ['data' => $data]);
        // ...
    }
    
  • Form Dump: Use Symfony’s form dumper to inspect submitted data:

    $form->submit($data);
    dump($form->getData());
    

Extension Points

  1. Custom Handlers: Extend AbstractHandler to add shared functionality (e.g., logging, notifications):

    abstract class LoggableHandler extends AbstractHandler
    {
        protected function logAction($action, $data)
        {
            $this->logger->info(sprintf('%s: %s', $action, json_encode($data)));
        }
    }
    
  2. Handler Decorators: Decorate handlers to add cross-cutting concerns (e.g., audit logging):

    class AuditHandlerDecorator implements HandlerInterface
    {
        private $handler;
        private $auditService;
    
        public function __construct(HandlerInterface $handler, AuditService $audit)
        {
            $this->handler = $handler;
            $this->auditService = $audit;
        }
    
        public function handle($data)
        {
            $this->auditService->log('form_submitted', $data);
            return $this->handler->handle($data);
        }
    }
    
  3. Configuration: Override default handler options in form types:

    $resolver->setDefaults([
        'handler' => new MyHandler(),
        'handler_options' => ['key' => 'value'], // Pass to handler
    ]);
    
  4. Testing: Mock handlers in unit tests:

    $handler = $this->createMock(HandlerInterface::class);
    $handler->method('handle')->willReturn(true);
    $form = $this->createForm(MyFormType::class, [], ['handler' => $handler]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator