How do you migrate from laminas-code 2 to 4, wrt. annotations?

Hey,

Good day.

We currently extend the AnnotationBuilder that exists in laminas-code 2. This however breaks in laminas-code 4 as the AnnotationBuilder class is final. I updated the class to not extend AnnotationBuilder and did the following with my createForm call:

namespace Application\Annotation;

use Application\Initializer\EntityManagerAwareInterface;
use Application\Initializer\EntityManagerAwareTrait;
use Laminas\Code\Annotation\Parser\DoctrineAnnotationParser;
use Laminas\Code\Annotation\AnnotationManager;
use Laminas\EventManager\EventManagerInterface;
use Laminas\Form\Annotation\AnnotationBuilder;

class Builder extends AnnotationBuilder implements EntityManagerAwareInterface
{
    use EntityManagerAwareTrait;

    public function createForm($entity)
    {
        $annotationBuilder = new EntityBasedFormBuilder($this->entityManager);
        $form = $annotationBuilder->createForm($entity);

        $hydrator = new DoctrineObject($this->entityManager, true);
        $form->setHydrator($hydrator);

        return $form;
    }

The bits I am not sure of is why my ‘id’ no longer works for an existing entity? I get the following message:

Additional information:
Laminas\Form\Exception\InvalidElementException
File:
/var/www/html/vendor/laminas/laminas-form/src/Fieldset.php                    :207
Message:
No element by the name of [id] found in form
Stack trace:
#0 /var/www/html/module/Litigation/view/litigation/matter/add.phtml(83): Laminas\Form\Fieldset->get('id')
#1 /var/www/html/vendor/laminas/laminas-view/src/Renderer/PhpRenderer.php(519): include('/var/www/html/m...')
#2 /var/www/html/vendor/laminas/laminas-view/src/View.php(194): Laminas\View\Renderer\PhpRenderer->render(NULL)
#3 /var/www/html/vendor/laminas/laminas-view/src/View.php(222): Laminas\View\View->render(Object(Laminas\View\Model\ViewModel))
#4 /var/www/html/vendor/laminas/laminas-view/src/View.php(187): Laminas\View\View->renderChildren(Object(Laminas\View\Model\ViewModel))
#5 /var/www/html/vendor/laminas/laminas-mvc/src/View/Http/DefaultRenderingStrategy.php(98): Laminas\View\View->render(Object(Laminas\View\Model\ViewModel))
#6 /var/www/html/vendor/laminas/laminas-eventmanager/src/EventManager.php(319): Laminas\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Laminas\Mvc\MvcEvent))
#7 /var/www/html/vendor/laminas/laminas-eventmanager/src/EventManager.php(171): Laminas\EventManager\EventManager->triggerListeners(Object(Laminas\Mvc\MvcEvent))
#8 /var/www/html/vendor/laminas/laminas-mvc/src/Application.php(360): Laminas\EventManager\EventManager->triggerEvent(Object(Laminas\Mvc\MvcEvent))
#9 /var/www/html/vendor/laminas/laminas-mvc/src/Application.php(341): Laminas\Mvc\Application->completeRequest(Object(Laminas\Mvc\MvcEvent))
#10 /var/www/html/public/index.php(31): Laminas\Mvc\Application->run()
#11 {main}

Another issue is that in my Builder that extended the AnnotationBuilder I had custom annotations. We added them using the DoctrineAnnotationParser. This however no longer exists either. Here’s a snippet:

    private $customAnnotations = array(
        'Guid',
        ...
    );

    public function setAnnotationManager(AnnotationManager $annotationManager)
    {
        parent::setAnnotationManager($annotationManager);

        $parser = new DoctrineAnnotationParser();

        foreach ($this->customAnnotations as $module => $annotationName) {
            if (is_numeric($module)) {
                $class = __NAMESPACE__ . '\\' . $annotationName;
            }
            else {
                $class = $module;
            }

            $parser->registerAnnotation($class);
        }
        $annotationManager->attach($parser);

        return $this;
    }

Any help would be much appreciated. Thanks.

Regards,
Jarrett

Hello and welcome to your forums! :smiley:

Please help us and add the namespaces for all classes otherwise it is nearly impossible to understand the code examples.
Thanks in advance! :+1:t3:

1 Like

Heyo,

I’ve done this breakage in laminas/laminas-code a long time ago: annotations are GONE from there. There’s nothing about parsing annotations in laminas/laminas-code anymore, as far as I know.

My endorsement is to use doctrine/annotations, if you need annotations, and PHP 8.0+ if you instead want to use attributes (plan for it: annotations had a good run, but they are certainly not the future).

In laminas/laminas-form, there’s the AnnotationBuilder, which builds its own AnnotationReader, from what I can see: https://github.com/laminas/laminas-form/blob/d854a5610889ff42d36076a46bb2422f37caa29b/src/Annotation/AnnotationBuilder.php#L35

This builder can be used to create a form, as documented in https://docs.laminas.dev/laminas-form/v3/form-creation/attributes-or-annotations/#using-docblock-annotations

I don’t know what EntityBasedFormBuilder is (or does), so I suggest writing an integration test around it (in your project), and moving on from there :slight_smile:

Marco Pivetta

https://twitter.com/Ocramius

https://ocramius.github.io/

I suspect DoctrineORMModule:

$entityManager = $container->get(\Doctrine\ORM\EntityManager::class);
$builder = new \DoctrineORMModule\Form\Annotation\EntityBasedFormBuilder($entityManager);

Ah, thanks for the reply. Updated, much appreciated. Thanks.

That’s correct. It works 99% of the way, when I step through the code, I can see all other form elements in the form object after calling createForm except the ‘id’. Assumed I’m missing something very easy and basic during migration efforts.

Hey,

Thanks for the info.

We are currently moving a ZF2 + PHP 7.3 app => Laminas + PHP 7.4. Not on PHP 8.0 just yet. Getting there. The system relies completely on annotations. Found your thread detailing its removal haha.

Will have a look at your links you shared. Probably move this question to the doctrine/annotations module instead then. Thanks again.

Regards,
Jarrett