Search code examples
zend-frameworkautoloadzend-framework3

Custom directory in src/ folder in ZF3


I have mvc zf3 skeleton with forms. Form and fieldset classes are located in src/Form directory.

Above works fine.

I tried to make the Form directory lighter and clearer so I created src/Fieldset directory and moved fieldset classes there. Now the fieldset classes are not found by form classes.

<?php

namespace Application\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\InputFilter\InputFilter;

class MyForm extends Form
{
    public function __construct()
    {
        parent::__construct('my_form');

        $this->setAttribute('method', 'post');
        $this->setHydrator(new ClassMethodsHydrator(false));
        $this->setInputFilter(new InputFilter());

        $this->add([
            'type' => AbcFieldset::class,
            'name' => 'abcEntity',
            'options' => [
                'use_as_base_fieldset' => true,
            ],
        ]);

The error message is

A plugin by the name "Application\Form\AbcFieldset" was not found in the plugin manager Zend\Form\FormElementManager\FormElementManagerV3Polyfill

What to do to make the form see the fieldset classes in new location?


Solution

  • The first problem is that the PSR-4 autoloader is looking for the Application\Form\AbcFieldset class in the file src/Form/AbcFieldset.php directory.

    You could write a custom autoloader that would look in the src/Fieldset directory, but it's better to stick with the PSR standard and instead change the namespace of the fieldset to Application\Fieldset (you will then need to add use Application\Fieldset\AbcFieldset; at the top of the form class in your example).

    The second 'problem', and the source of the error message is that the fieldset class has not been explicitly registered with the form element manager, so you might also add to your module.config.php

    'form_elements' => [
        'factories' => [
            \Application\Fieldset\AbcFieldset::class => \Zend\ServiceManager\Factory\InvokableFactory::class,
        ]
    ]
    

    But this isn't necessary unless you need to write a custom factory for the fieldset - the namespace change above should fix the problem.