Как валидировать такой массив данных?

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Как валидировать такой массив данных?

Сообщение dds »

Здравствуйте! Имеется экшен

Код: Выделить всё

$model = new Questions( Questions::getScenarioName( Questions::FORM_TYPE_REQUET_AVAILABILITY ) );

        if( !empty( $productCode ) ){
            $model->productCode = $productCode;
        }

        if( Yii::app()->request->getParam('Questions') ){

                 $model->attributes = Yii::app()->request->getParam('Questions');
                 if( $model->validate() && $model->save() ){

                $model->send();

                echo 1;
                Yii::app()->end();

            }

        }
тут

Код: Выделить всё

$model->attributes = Yii::app()->request->getParam('Questions');
атрибуты принимают вот такой массив :

Код: Выделить всё

Array
(
    [firstName] => 
    [phone] => 
    [email] => 
    [0] => Array
        (
            [productCode] => 
            [count] => 
            [replacement] => 0
        )

)
И валидируются только первые 3 ключа, а массив с ключом НОЛЬ и его элементами остается в стороне...таких массивов у меня может быть несколько еще например :

Код: Выделить всё

Array
(
    [firstName] => 
    [phone] => 
    [email] => 
    [0] => Array
        (
            [productCode] => 
            [count] => 
            [replacement] => 0
        )
   [1] => Array
        (
            [productCode] => 
            [count] => 
            [replacement] => 0
        )
)
Как мне провести валидацию этих 0 и 1 ?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Как валидировать такой массив данных?

Сообщение ElisDN »

Переименуйте поля в форме и в модель добавьте, например, public $products, чтобы приходило так:

Код: Выделить всё

Array
(
    [firstName] => 
    [phone] => 
    [email] => 
    [products] =>
        [0] => Array
            (
                [productCode] => 
                [count] => 
                [replacement] => 0
            )
) 
А потом в модели напишите для этого поля валидатор.
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

ElisDN писал(а):Переименуйте поля в форме и в модель добавьте, например, public $products, чтобы приходило так:

Код: Выделить всё

Array
(
    [firstName] => 
    [phone] => 
    [email] => 
    [products] =>
        [0] => Array
            (
                [productCode] => 
                [count] => 
                [replacement] => 0
            )
)
А потом в модели напишите для этого поля валидатор.
а примерчик можно валидатора?

теперь массив данных выглядит так:

Код: Выделить всё

Array
(
    [firstName] => 
    [phone] => 
    [email] => 
    [productCode] => Array
        (
            [0] => 123
            [1] => 12312312
        )

)
  
В моделе у меня в rules:

Код: Выделить всё

array(
                'productCode,
                firstName,
                 email,
                 phone', 'required', 'on' => self::getScenarioName( self::FORM_TYPE_REQUET_AVAILABILITY )
            ),
            array(
                'productCode', 'validateAttr', 'on' => self::getScenarioName( self::FORM_TYPE_REQUET_AVAILABILITY )
            ),
  
B сам валидатор в моделе:

Код: Выделить всё

public function validateAttr()
    {
        foreach($this->productCode as $key => $code){
                    if (empty($code)) {
                        $this->addError('productCode['.$key.']', 'Поле должно быть заполнено');
                        break;
                    }
        }
    }
  
Выдает ошибку:

Код: Выделить всё

Invalid argument supplied for foreach() и указывает на эту строку в моделе - $this->addError('productCode['.$key.']', 'Поле должно быть заполнено');
  
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

Код: Выделить всё

    public $questions; // объявляем атрибут модели

    public function attributeNames() {
        return array(
            'questions',
        );
    }

    public function attributeLabels() {
        return array(
            'questions' => 'Вопросы',
        );
    }

    public function rules() {
        return array(
            array('questions', 'checkQuestions'), // объявляем правило проверки атрибута
        );
    }

    /**
     * Проверка значения атрибута "questions"
     * Валидатор для использования в rules().
     * @param       string      $attribute      Наименование атрибута
     * @param       array       $params         Дополнительные параметры
     * @return      boolean
     */
    public function checkQuestions($attribute, $params) {
        $data = filter_input(INPUT_POST, get_class($this), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
        if (!isset($data[$attribute])){
            $this->addError($attribute, sprintf('Необходимо заполнить поле «%s».', $this->getAttributeLabel($attribute)));
            return false;
        }
        foreach ($data[$attribute] as $key => $value) {
        // проверка значений
        }
    }
 
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):

Код: Выделить всё

    public $questions; // объявляем атрибут модели

    public function attributeNames() {
        return array(
            'questions',
        );
    }

    public function attributeLabels() {
        return array(
            'questions' => 'Вопросы',
        );
    }

    public function rules() {
        return array(
            array('questions', 'checkQuestions'), // объявляем правило проверки атрибута
        );
    }

    /**
     * Проверка значения атрибута "questions"
     * Валидатор для использования в rules().
     * @param       string      $attribute      Наименование атрибута
     * @param       array       $params         Дополнительные параметры
     * @return      boolean
     */
    public function checkQuestions($attribute, $params) {
        $data = filter_input(INPUT_POST, get_class($this), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
        if (!isset($data[$attribute])){
            $this->addError($attribute, sprintf('Необходимо заполнить поле «%s».', $this->getAttributeLabel($attribute)));
            return false;
        }
        foreach ($data[$attribute] as $key => $value) {
        // проверка значений
        }
    }
Данный вариант не работает у меня=(
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

Что именно не работает? Адаптируйте код под свои данные. Код абсолютно рабочий. Валидация работает как на весь атрибут, так и на значение атрибута.
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):Что именно не работает? Адаптируйте код под свои данные. Код абсолютно рабочий. Валидация работает как на весь атрибут, так и на значение атрибута.
не могли бы вы, если не сложно, функцию валидатора продемонстировать в моем случае...а именно как провалидировать productCode в массиве?
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

вроде так должно получиться

Код: Выделить всё

    public $products; // объявляем атрибут модели

    public function attributeNames() {
        return array(
            'products',
        );
    }

    public function attributeLabels() {
        return array(
            'products' => 'Продукты',
        );
    }

    public function rules() {
        return array(
            array('questions', 'checkProducts', 'on' => self::getScenarioName( self::FORM_TYPE_REQUET_AVAILABILITY), // объявляем правило проверки атрибута для вашего сценария
        );
    }

    /**
     * Проверка значения атрибута "questions"
     * Валидатор для использования в rules().
     * @param       string      $attribute      Наименование атрибута
     * @param       array       $params         Дополнительные параметры
     * @return      boolean
     */
    public function checkProducts($attribute, $params) {
        $data = filter_input(INPUT_POST, get_class($this), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
        if (!isset($data[$attribute])){
            $this->addError($attribute, sprintf('Необходимо заполнить поле «%s».', $this->getAttributeLabel($attribute)));
            return false;
        }
        foreach ($data[$attribute] as $key => $row) {
            if (!is_numeric($row['ncode'])) {
                $this->addError(sprintf('products[%s][ncode]', $key), 'Код должен быть числом.');
            }
        }
    }
 


представление

Код: Выделить всё

<?= CHtml::activeTextField($model, "products[$key][ncode]"); ?>
<?= CHtml::error($model, "products[$key][ncode]"); ?>
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):вроде так должно получиться

Код: Выделить всё

    public $products; // объявляем атрибут модели

    public function attributeNames() {
        return array(
            'products',
        );
    }

    public function attributeLabels() {
        return array(
            'products' => 'Продукты',
        );
    }

    public function rules() {
        return array(
            array('questions', 'checkProducts', 'on' => self::getScenarioName( self::FORM_TYPE_REQUET_AVAILABILITY), // объявляем правило проверки атрибута для вашего сценария
        );
    }

    /**
     * Проверка значения атрибута "questions"
     * Валидатор для использования в rules().
     * @param       string      $attribute      Наименование атрибута
     * @param       array       $params         Дополнительные параметры
     * @return      boolean
     */
    public function checkProducts($attribute, $params) {
        $data = filter_input(INPUT_POST, get_class($this), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY);
        if (!isset($data[$attribute])){
            $this->addError($attribute, sprintf('Необходимо заполнить поле «%s».', $this->getAttributeLabel($attribute)));
            return false;
        }
        foreach ($data[$attribute] as $key => $row) {
            if (!is_numeric($row['ncode'])) {
                $this->addError(sprintf('products[%s][ncode]', $key), 'Код должен быть числом.');
            }
        }
    }


представление

Код: Выделить всё

<?= CHtml::activeTextField($model, "products[$key][ncode]"); ?>
<?= CHtml::error($model, "products[$key][ncode]"); ?>
А в контроллере? просто $model->validate()?
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

А в контроллере? просто $model->validate()?
именно, либо $model->save(true, $model->attributes)
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):
А в контроллере? просто $model->validate()?
именно, либо $model->save(true, $model->attributes)
Валидация заработала спасибо! только вот когда 1 из 2ух полей заполняешь и нажимаешь сабмит то не сохраняет значения уже введенного поля... в инпуте, как быть с этим?
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

Такого не может быть. Проверьте данные трассировкой заголовков браузера и в данных приходящих на сервер ($_POST). Если данные есть и валидация прошла успешно, тогда ошибка в выводе.
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):Такого не может быть. Проверьте данные трассировкой заголовков браузера и в данных приходящих на сервер ($_POST). Если данные есть и валидация прошла успешно, тогда ошибка в выводе.
В $_POST приходит всё, валидация проходит, но value инпута пустое... =( точнее его вообще нет.
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

В $_POST приходит всё, валидация проходит, но value инпута пустое... =( точнее его вообще нет.
Вы сами поняли что написали? Я - нет. Рекомендую вам почитать мануалы. Мне кажется вы не понимаете что делаете.
dds
Сообщения: 102
Зарегистрирован: 2013.11.18, 10:48

Re: Как валидировать такой массив данных?

Сообщение dds »

pegas1981 писал(а):
В $_POST приходит всё, валидация проходит, но value инпута пустое... =( точнее его вообще нет.
Вы сами поняли что написали? Я - нет. Рекомендую вам почитать мануалы. Мне кажется вы не понимаете что делаете.
Что именно непонятно? Отправляю форму - при этом оставляю 1 из 2ух полей пустым, проходит валидация что 1 поле не заполнено, а во втором поле должно остаться предыдущее значение (value в инпуте должно равняться предыдущему введенному значению и $_POST) - оно же пустое, пропадает....и его нужно каждый раз перезабивать... поля со стандартной валидацией работают кооректно...
pegas1981
Сообщения: 35
Зарегистрирован: 2012.05.15, 16:54

Re: Как валидировать такой массив данных?

Сообщение pegas1981 »

Публикуйте свой код MVC. Если бы вы сделали всё правильно, то модель бы заполнилась автоматически. Я поэтому и говорю, что вы сами не понимаете что делаете.
Ответить