Arhn - архитектура программирования

Требуется хотя бы один элемент в ZF2 FieldSet

Проблема

У меня есть Form и FieldSet. Я хотел бы подтвердить, что FieldSet не пуст. Кроме того, я хочу проверить каждое поле в файле FieldSet.

До сих пор все, что я пробовал, подтверждало одно или другое, но не оба. Если elements присутствует в спецификации входного фильтра формы, то он подтверждает, что elements не является пустым, но не проверяет поля bar и baz в FieldSet. И, конечно же, наоборот. Любая подсказка относительно того, как подойти к этому вопросу, будет высоко оценена.

Форма

class FooForm extends Form implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add([
            'name'     => 'elements',
            'type'     => Collection::class,
            'required' => true,
            'options'  => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class
                ]
            ]
        ]);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'        => 'elements',
                'required'    => true,
                'validators'  => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
}

Набор полей

class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add(['name' => 'bar']);
        $this->add(['name' => 'baz']);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'bar',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
            [
                'name'       => 'baz',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
}

Изменить: добавлена ​​полная спецификация проверки.


  • Возможно, вам придется обновить свой пример. Ваша форма добавляет SomeElement::class, но я думаю, что вы упомянули SomeElementFieldset::class или вы зарегистрировали это таким образом в своей конфигурации? Тем не менее, это незначительная проблема, вы можете прочитать документацию о Коллекции форм. Вы можете установить параметр count для набора полей равным 1, чтобы получить хотя бы одну запись набора полей. Как и в документах, они не добавляют набор полей в формы ::getInputFilterSpecifications(). 06.06.2017
  • Спасибо, что заметили, это действительно была опечатка. Честно говоря, я несколько раз просматривал документацию и несколько часов безуспешно гуглил, прежде чем прийти сюда. :) Пробовал устанавливать count в 1 или даже больше, на всякий случай, не помогло. И проблема с исключением набора полей из getInputFilterSpecification() заключается в том, что тогда он не проверяет количество, и набор полей может оказаться пустым. 06.06.2017
  • Вы установили необходимые параметры для полей в пределах getInputFilterSpecification() вашего набора полей? Может помочь показать, какие валидаторы/фильтры вы привязываете к полям: bar и baz, вместо комментария: // проверка для bar и baz. Например, некоторые люди используют валидаторы NotEmpty, что очень похоже на обязательные параметры. 06.06.2017
  • Извините за поздний ответ, я добавил больше кода. Хотя на самом деле не имеет значения, какие валидаторы я туда поставлю, они просто не запускаются вообще. 24.06.2017

Ответы:


1

Получив несколько советов в Google и покопавшись в исходном коде, я нашел решение. К сожалению, реализация zend-inputfilter немного ошибочна и не будет хорошо работать с getInputFilterSpecification(), но мы можем просто создать свою собственную InputFilter и вернуть ее напрямую:

Форма

class FooForm extends BaseForm
{
    public function init()
    {
        $this->add([
            'name'    => 'elements',
            'type'    => Collection::class,
            'options' => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class
                ]
            ]
        ]);
    }

    public function getInputFilter()
    {
        if (!$this->filter) {
            $this->filter = new InputFilter();

            /** @var Collection $elementsCollection */
            $elementsCollection = $this->fieldsets['elements'];

            /** @var SomeElementFieldSet $elementsFieldSet */
            $elementsFieldSet = $elementsCollection->getTargetElement();

            $collectionFilter = new CollectionInputFilter();
            $collectionFilter->setIsRequired(true);
            $collectionFilter->setInputFilter(
                $elementsFieldSet->getInputFilterSpecification()
            );

            $this->filter->add($collectionFilter, 'elements');
        }

        return $this->filter;
    }
}

Это подтвердит наличие хотя бы одного элемента в коллекции. И будет проверять все элементы один за другим по спецификации FieldSet.

Однако остается одна проблема. Всякий раз, когда коллекция пуста, проверка возвращает false, но не возвращает никаких сообщений. Это связано с ошибкой в ​​компоненте zend-inputfilter. О проблемах сообщалось здесь и здесь. Но это совсем другая проблема.

26.06.2017

2

Используйте метод setValidationGroup() в объекте Form, указав массив полей ввода, которые вы хотите проверить. См. Док!

Вы можете попробовать этот способ. Хотя я добавил несколько дополнительных полей в форму только для тестирования.

class FooForm extends Form implements InputFilterProviderInterface
{
     public function __construct($name = null, $options = array())
     {

        parent::__construct($name, $options);

        $this->add(['name' => 'title']);

        $this->add([
            'name'     => 'elements',
            'type'     => Collection::class,
            'required' => true,
            'options'  => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class,
                ],
            ],
        ]);

        $this->add([
            'type' => 'submit',
            'name' => 'submit',
            'attributes' => [
                 'value' => 'Post'
            ],
        ]);

        // I pointed this. Here you can specify fields to be validated
        $this->setValidationGroup([
            'title',
            'elements' => [
                'bar',
            ],
        ]);         
     }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'title',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
        ];
    }     
}

И ваш класс fieldset должен быть

class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add(['name' => 'bar']);
        $this->add(['name' => 'baz']);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'bar',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
            [
                'name'       => 'baz',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
} 

Надеюсь, это поможет!

06.06.2017
  • Группы проверки не решат эту проблему, так как я не хочу проверять подмножество полей, а скорее проверять, что в наборе полей есть некоторые элементы, а затем проверять все поля набора полей. 24.06.2017
  • Уверены ли вы? Отредактировал код и изменил DOC. Пожалуйста, посмотрите! Я тестировал с ZF2.4. Оно работает. Дайте нам знать. Спасибо 24.06.2017
  • Спасибо за дополнительный код, попробую еще раз и дам вам знать. :) 25.06.2017
  • Извините, но этот код не сработал. Он никогда не проверял пустую коллекцию. Спасибо, в любом случае! ;) 26.06.2017
  • Мне очень жаль, что он вам не помог! :( 26.06.2017
  • Не беспокойтесь, я ценю усилия, несмотря ни на что. ;) 26.06.2017
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..