ZF2/Doctrine2 - Fieldsets not validated, data is always valid

前端 未结 2 1994
暖寄归人
暖寄归人 2020-12-21 20:07

I\'ve set up a structure using Abstract classes for Forms, Fieldsets and InputFilters. Forms and Fieldsets have Factories while InputFilters are created and set on the Field

2条回答
  •  猫巷女王i
    2020-12-21 20:31

    Since you've got all the classes set up already there is another approach (from @AlexP), by constructing and adding the InputFilters of the Fieldsets to the Forms InputFilter. Instead of using the InputFilterSpecifications.

    So add the input filters to your input_filters config key:

    'form_elements' => [
        'factories' => [
            CountryForm::class => CountryFormFactory::class,
            CountryFieldset::class => CountryFieldsetFactory::class,
        ],
    ],
    'input_filters' => [
        'factories' => [
            CountryInputFilter::class => CountryInputFilterFactory::class,
            CountryFieldsetInputFilter::class => CountryFieldsetInputFilterFactory::class,
        ],
    ],
    

    Factory classes:

    class CountryInputFilterFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            $serviceManager = $serviceLocator->getServiceLocator();
    
            $inputFilter = new CountryInputFilter(
                $serviceLocator->get(CountryFieldsetInputFilter::class),
                $serviceManager()->get('Doctrine\ORM\EntityManager'),
                $serviceManager()->get('translator')
            );
    
            return $inputFilter;
        }
    }
    
    class CountryFieldsetInputFilterFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            $serviceManager = $serviceLocator->getServiceLocator();
    
            return new CountryFieldsetInputFilter(
                $serviceManager()->get('Doctrine\ORM\EntityManager'),
                $serviceManager()->get('translator')
            );
        }
    }
    
    class CountryFormFactory implements AbstractFormFactory
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            $serviceManager = $serviceLocator->getServiceLocator();
    
            $form = new CountryForm($this->name, $this->options);
            $form->setObjectManager($serviceManager->get('Doctrine\ORM\EntityManager'));
            $form->setTranslator($serviceManager->get('translator'));
    
            $form->setInputFilter($serviceManager->get('InputFilterManager')->get(CountryInputFilterFactory::class));
            return $form;
        }
    }
    

    Form:

    class CountryForm extends AbstractForm
    {
        const COUNTRY_FIELDSET_NAME = 'country';
    
        // This one added for SO, does nothing but call parent#__construct, which would happen anyway
        public function __construct($name = null, array $options)
        {
            parent::__construct($name, $options);
        }
    
        public function init()
        {
            //Call parent initializer.
            parent::init();
    
            $this->add([
                'name' => self::COUNTRY_FIELDSET_NAME,
                'type' => CountryFieldset::class,
                'options' => [
                    'use_as_base_fieldset' => true,
                ],
            ]);
        }
    }
    

    InputFilters:

    class CountryInputFilter extends AbstractInputFilter
    {
        /** @var CountryFieldsetInputFilter  */
        protected $countryFieldsetInputFilter;
    
        public function __construct(CountryFieldsetInputFilter $filter, $objectManager, $translator)
        {
            $this->countryFieldsetInputFilter = $filter;
            // other dependencies
        }
    
        public function init()
        {
            $this->add($this->countryFieldsetInputFilter, CountryForm::COUNTRY_FIELDSET_NAME);
        }
    }
    
    class CountryFieldsetInputFilter extends AbstractInputFilter
    {
        public function __construct($objectManager, $translator)
        {
            // dependencies
        }
    
        public function init()
        {
            $this->add([
                // configuration
            ]);
        }
    }
    

    Note that I injected the dependencies to the InputFilters per argument by instance instead of an array holding the instances.

提交回复
热议问题