Fieldset Validation Not Being Applied

Hello Laminas Community!

I’ve got a simple fieldset that is successfully hydrating the expected entity, however, the validation in that fieldset’s getInputFilterSpecification is being ignored.

The fieldset belongs to a Collection, which is added to the base form as such:

        $this->add([
            'name' => 'skill_rewards',
            'type' => Collection::class,
            'options' => [
                'label' => 'Skill Rewards',
                'allow_add' => true,
                'target_element' => $this->skillRewardFieldset,
            ],
        ]);

The FieldSet’s construction is as follows:

class StepSkillRewardFieldset extends Fieldset implements InputFilterProviderInterface
{
    private ObjectManager $objectManager;

    public function __construct(ObjectManager $objectManager, ?string $name = null, array $options = [])
    {
        parent::__construct($name, $options);
        $this->objectManager = $objectManager;
    }

    public function init()
    {
        $this->add([
            'name' => 'skill',
            'type' => ObjectSelect::class,
            'options' => [
                'property' => 'id',
                'target_class' => Skill::class,
                'object_manager' => $this->objectManager,
            ],
        ]);

        $this->add([
            'name' => 'points_rewarded',
            'type' => Number::class,
            'options' => [
                'label' => 'Points Rewarded',
            ],
        ]);
    }

    /**
     * @inheritDoc
     */
    public function getInputFilterSpecification()
    {
        return [
            'points_rewarded' => [
                'required' => true,
                'filters' => [
                    ['name' => ToInt::class],
                ],
                'validators' => [
                    [
                        'name' => GreaterThan::class,
                        'options' => [
                            'min' => 1,
                            'inclusive' => true,
                        ],
                    ],
                ],
            ],
            'skill' => [
                'required' => true,
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                    ],
                ],
            ],
        ];
    }
}

Despite this configuration, I am still able to push zero values for example into points_rewarded, and the system is happy to hydrate the object with a zero point value.

Am I missing a vital config option that would ask the Collection to apply the fieldset’s validation?

Thanks for the steer!

Looks like you found already the answer in the chat:

1 Like

Passing the entity manager is useless here, as the element already has it:

Regardless, if the element needs the entity manager or database adapter, then the fieldset or form doesn’t need to know about it. It is not necessary to pass the entity manager, adapter or anything else through all the layers of a form. Use a factory or delegator for the element instead.

Thanks for the conversation @froschdesign! We might be working across version differences? If I don’t specify the EM as was done, this is the extant error:

<div class="error_details">
                                    <hr/>
                <h3>Additional information:</h3>
                <dl>
                    <dt>File:</dt>
                    <dd>
                        <pre class="prettyprint linenums">/vendor/doctrine/doctrine-module/src/Form/Element/Proxy.php: 218</pre>
                    </dd>
                    <dt>Message:</dt>
                    <dd>
                        <pre class="prettyprint linenums">No object manager was set</pre>
                    </dd>
                    <dt>Stack trace:</dt>
                    <dl>
                        <pre class="prettyprint linenums">#0 /vendor/doctrine/doctrine-module/src/Form/Element/Proxy.php(356): DoctrineModule\Form\Element\Proxy-&gt;getObjectManager()
#1 /vendor/doctrine/doctrine-module/src/Form/Element/ObjectSelectV3Polyfill.php(61): DoctrineModule\Form\Element\Proxy-&gt;getValue(Object(DoctrineORMModule\Proxy\__CG__\Lemonade\Entity\Skill))
#2 /vendor/laminas/laminas-form/src/Fieldset.php(380): DoctrineModule\Form\Element\ObjectSelectV3Polyfill-&gt;setValue(Object(DoctrineORMModule\Proxy\__CG__\Lemonade\Entity\Skill))
#3 /vendor/laminas/laminas-form/src/Element/Collection.php(243): Laminas\Form\Fieldset-&gt;populateValues(Array)

It is indeed being pushed in via Factory.

Do you create the form via the form element manager?

See:

Yep! They’re created with the FM.

Why is the factory for ObjectSelect in the ORM module and the factory for EntitySelect is missing? And why is the entity manager set on the ObjectSelect element?
Very confused!

(I am not familiar with the Doctrine modules and do not use them either.)