Search code examples
zend-frameworkannotationszend-formmezzio

inject dependency in action on form built with Zend\Form\Annotation\AnnotationBuilder with zend expressive


I am trying to replace the Zend_Db usage in the zend expressive album tutorial with doctrine. On top of this, I want to remove the album form and form factory with a form built with the zend form annotationbuilder. I get the annotationbuilder working and receive a working form.

In the tutorial, the form is defined as dependency in the album.global.config:

<?php
return [
  'dependencies' => [
    'factories' => [
      ...     
      Album\Form\AlbumDataForm::class =>
      Album\Form\AlbumDataFormFactory::class,
      ...
    ],
  ],
  'routes' => [
    ...
    [
        'name'            => 'album-update-handle',
        'path'            => '/album/update/:id/handle',
        'middleware'      => [
            Album\Action\AlbumUpdateHandleAction::class,
            Album\Action\AlbumUpdateFormAction::class,
        ],
        'allowed_methods' => ['POST'],
        'options'         => [
            'constraints' => [
                'id' => '[1-9][0-9]*',
            ],
        ],
    ],
    ...
  ],
];

... and injected into the actions AlbumUpdateFormAction.php and AlbumUpdateFormHandleAction.php:

<?php
...
class AlbumUpdateFormAction
{
  public function __construct(
    TemplateRendererInterface $template,
    AlbumRepositoryInterface $albumRepository,
    AlbumDataForm $albumForm
  ) {
    $this->template        = $template;
    $this->albumRepository = $albumRepository;
    $this->albumForm       = $albumForm;
  }
  public function __invoke(
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next = null
  ) {
    ...
    if ($this->albumForm->getMessages()) {
      $message = 'Please check your input!';
    } else {
      $message = 'Please change the album!';
    }
    ...
  }
}

This is needed because of the usage of the "handle action". If errors occur in the form validation, the next middleware is called. Now, the error messages of the form elements are extracted and shown if ($this->albumForm->getMessages()) {

This is exactly my problem. I get the form working, but when the next middleware is called Album\Action\AlbumUpdateHandleAction::class my form is empty because I generate it "from scratch" in both middlewares. What I need to do, is either to define my annotationuilder built form as dependency and inject it to the middleware or to pass it from one middleware to the other.

But I don't know how to accomplish this. Any ideas are very welcome!

I hope, I have made myself clear. I must admit that I am quite new to zend expressive and the related concepts. Thanks in advance, LT


Solution

  • The zend-expressive concept is about middleware. What and how you do something in your actions is completely up to you. There are no set rules or best practices to handle a form since you are free to use any solution that fits your needs. Using an update and handle action is one of the many possibilities.

    What you can do to pass data to the the the following middleware is injecting it into the request:

    return $next($request->withAttribute('albumForm', $albumForm), $response);
    

    I have explained that concept over here.

    Also you can try an easier concept and see if that works out with what you want. You can merge AlbumUpdateHandleAction and AlbumUpdateFormAction into an AlbumUpdateAction. This way you don't need to pass the data towards the next middleware since all related tasks are handled inside the same action.