0

我有一个相当复杂的表格,它以选项卡格式呈现。表单中的任何一个字段集都需要完成,所以我正在考虑使用 OptionalInputFilter。我遇到问题的字段集是一个集合。我已将输入过滤器配置为可以与集合一起使用,但可选方面似乎无法解决问题。需要明确的是,所需的效果是用户可以添加一组项目,其中每个元素都经过过滤/验证,或者用户将其留空,并且它通过验证。

有问题的字段集:

class EventFieldset extends Fieldset
{
    public function __construct($name = null, $options = [])
    {
        parent::__construct('Events', $options);
    }

    public function init()
    {
        $this->add([
            'name' => 'date',
            'type'  => Date::class,
            'options' => [
            'label' => 'Date',
            'label_attributes' => [
                'class' => 'col-form-label'
            ],
        ],
        'attributes' => [
            'class' => 'form-control ',
            'required' => true,
        ],
    ]);

    $this->add([
        'name' => 'description',
        'type'  => Textarea::class,
        'options' => [
            'label' => 'Description',
            'label_attributes' => [
                'column' => 'md-2',
                'class' => 'col-form-label'
            ],
        ],
        'attributes' => [
            'class' => 'form-control',
            'minlength' => '10',
            'required' => true,
        ],
    ]);

    $this->add([
        'name' => 'hours',
        'type'  => Text::class,
        'options' => [
            'label' => 'Hours',
            'label_attributes' => [
                'column' => 'md-2',
                'class' => 'col-form-label'
            ],
           'column' => 'md-10'
        ],
        'attributes' => [
            'class' => 'has-event-duration duration-only form-control'
        ],
    ]);

}

}

上述字段集的输入过滤器:

class EventInputFilter extends OptionalInputFilter
{
public function init()
{
    parent::init();
    $this->add([
        'name' => 'date',
        'validators' => [
            [
                'name' => Date::class,
                'options' => [
                    'format' => 'Y-m-d',
                    'strict' => true,
                ]
            ],
        ],
        'filters' => [
            ['name' => StripTags::class],
            [
                'name' => DateTimeFormatter::class,
                'options' => [
                    'format' => 'Y-m-d'
                ]
            ]
        ]
    ]);

    $this->add([
        'name' => 'description',
        'required' => true,
        'validators' => [
            [
                'name' => StringLength::class,
                'options' => [
                    'min' => 5,
                    'max' => 25600
                ]
            ]
        ],
        'filters' => [
            ['name' => StripTags::class],
            ['name' => StringTrim::class]
        ]
    ]);

    $this->add([
        'name' => 'hours',
        'required' => true,
        'validators' => [
            ['name' => AlnumValidator::class],
        ],
        'filters' => [
            ['name' => StripTags::class],
            ['name' => Alnum::class]
        ]
    ]);

}

}

注意它是如何扩展 OptionalInputFilter 的。

表格:

class MyForm extends Form
{
public function init()
{
    parent::init();
    //other elements / fieldsets removed for brevity
    $this->add([
        'name' => 'manualRecords',
        'type' => ManuallyEnteredRecordsFieldset::class,
    ]);

    $this->add([
        'type' => Csrf::class,
        'name' => 'csrf',
        'options' => [
            'csrf_options' => [
                'timeout' => 600,
            ],
        ],
    ]);

    $this->add([
        'name' => 'Submit',
        'type' => Submit::class,
        'options' => [
            'label' => 'Submit',
            'variant' => 'outline-primary'
        ],
        'attributes' => [
            'class' => 'btn btn-primary',
            'value' => 'Submit'
        ]
    ]);
}

}

class ManuallyEnteredRecordFieldset extends Fieldset
{
public function init()
{
    //other elements here - removed for brevity
    $this->add([
        'name' => 'Events',
        'type' => Collection::class,
        'options' => [
            'count' => 1,
            'allow_add' => true,
            'should_create_template' => true,
            'target_element' => [
                'type' => EventFieldset::class
            ],
        ]
    ]);

最后,在表单工厂中添加输入过滤器:

class MyFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    $form = new MyForm();
    $form->setInputFilter($this->getInputFilter($container->get('InputFilterManager')));
    return $form;
}

protected function getInputFilter(InputFilterPluginManager $inputFilterPluginManager) : InputFilter
{
    //other input filters applied - removed for brevity
    $eventInputFilter = $inputFilterPluginManager->get(EventInputFilter::class);

    $baseInputFilter = new InputFilter();

    $collectionInputFilter = new CollectionInputFilter();
    $collectionInputFilter->setInputFilter($eventInputFilter);
    $manualRecordInputFilter = new OptionalInputFilter();   //note - also an OptionalInputFilter
    $manualRecordInputFilter->add($collectionInputFilter, 'Events');
    $baseInputFilter->add($manualRecordInputFilter, 'manualRecords');

    return $baseInputFilter;
}

}

当我提交带有数据的表单时,即使添加了 1->N 行的集合,也可以很好地验证它。如果没有输入任何数据(由于它是从可选的 Inputfilter 构建的,我希望它仍然会通过),我会收到以下 inputfilter 错误消息:

["manualRecords"] => array(2) {
["Events"] => array(1) {
  [0] => array(3) {
    ["date"] => array(2) {
      ["isEmpty"] => string(36) "Value is required and can't be empty"
    }
    ["description"] => array(1) {
      ["isEmpty"] => string(36) "Value is required and can't be empty"
    }
    ["hours"] => array(1) {
      ["isEmpty"] => string(36) "Value is required and can't be empty"
    }
  }
}

这不是行为应该遵循的方式: https ://docs.laminas.dev/laminas-inputfilter/optional-input-filters/

4

0 回答 0