форма - валидация данных - база данных

вот такой вопрос назрел. есть ли возможность

в модели "перехватывать" данные формы для

коррекции, например для текстовых полей

использовать htmlspecialchars(),

для последующего сохранения в базе данных?

в модели существуют 2 экшана: actionAdd (insert),

actionEdit (update). хотелось бы создать общее

правило для них.

1.    получили данные (POST)

2.    валидация

2.1. если введено неверно - сообщение пользователю

      над формой ввода

2.2 введено верно - сохраняем в базу  :)

В модели есть методы:

beforeValidate() и

beforeSave()

  • можешь их использовать…

Quote

в модели существуют 2 экшана: actionAdd (insert),

actionEdit (update). хотелось бы создать общее

правило для них.

или ты имел ввиду контроллер (судя по action*)???

Quote

или ты имел ввиду контроллер (судя по action*)???
  • контроллер

Quote

В модели есть методы: beforeValidate() и beforeSave()
  • здорово, получилось.

  как теперь пометить некорректные данные ошибкой и

  вывести на экран вместе с формой ввода?

в модели есть типа $this->addError('password','Incorrect password.') .

как после валидации даных в конролере вывести ERROR и форму ввода?

Quote

Quote

В модели есть методы: beforeValidate() и beforeSave()
  • здорово, получилось.

  как теперь пометить некорректные данные ошибкой и

  вывести на экран вместе с формой ввода?

в модели есть типа $this->addError('password','Incorrect password.') .

как после валидации даных в конролере вывести ERROR и форму ввода?

Это можно сделать в представлении:

<?php echo CHtml::errorSummary($model); ?>

Попробуйте сгенерировать crud для своей модели в консольной утилите yiic, проанализируйте представления, посмотрите как это рекомендует делать автор фреймворка.

что бы заработал механизм форма - валидация данных - база данных делаем так:

1. в модели

[tt]    protected function beforeValidate($on)

    {

        $result = true;

        if (isset($_POST['News']['dat'])) {  //дата вводится в формате "dd.mm.yyyy"

            list($d['dd'], $d['mm'], $d['yy']) = explode('.', $_POST['News']['dat']);

            if (checkdate($d['mm'], $d['dd'], $d['yy'])) {  //проверка корректности даты

                $this->dat = $d['yy'] .'-'. $d['mm'] .'-'. $d['dd'];  //переделать в фотмат mysql "yyyy-mm-dd"

            }

            else {

                $this->addError('News date','Incorrect date.');  //ОШИБКА!!!

                $result = false;

            }

        }

        return $result;

    }[/tt]

2. в контроллере

[tt]    public function actionAdd() {

        if(isset($_POST['News'])) {

            $rec = new News;

            $rec->attributes = $_POST['News'];

            $rec->save;    //тут срабатывает beforeValidate() модели

            if($rec->hasErrors()) {

                //вызвать представление и передать туда ошибку                  $this->render('form',array('errorSummary'=>CHtml::errorSummary($rec),'row'=>$_POST['News']));

                return;

            }

            $this->redirect(array('edit','id'=>$rec->id);

        }

        $this->render('form');

    }[/tt]

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

[tt]    if (isset($errorSummary)) {

        echo $errorSummary;

    }[/tt]

Quote

что бы заработал механизм форма - валидация данных - база данных делаем так:

1. в модели

[tt]    protected function beforeValidate($on)

    {

        $result = true;

        if (isset($_POST['News']['dat'])) {  //дата вводится в формате "dd.mm.yyyy"

            list($d['dd'], $d['mm'], $d['yy']) = explode('.', $_POST['News']['dat']);

            if (checkdate($d['mm'], $d['dd'], $d['yy'])) {  //проверка корректности даты

                $this->dat = $d['yy'] .'-'. $d['mm'] .'-'. $d['dd'];  //переделать в фотмат mysql "yyyy-dd-mm"

            }

            else {

                $this->addError('News date','Incorrect date.');  //ОШИБКА!!!

                $result = false;

            }

            return $result;

        }

    }[/tt]

2. в контроллере

[tt]    public function actionAdd() {

        if(isset($_POST['News'])) {

            $rec = new News;

            $rec->attributes = $_POST['News'];

            $rec->save;    //тут срабатывает beforeValidate() модели

            if($rec->hasErrors()) {

                //вызвать представление и передать туда ошибку                  $this->render('form',array('errorSummary'=>CHtml::errorSummary($rec),'row'=>$_POST['News']));

                return;

            }

            $this->redirect(array('edit','id'=>$rec->id);

        }

        $this->render('form');

    }[/tt]

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

[tt]    if (isset($errorSummary)) {

        echo $errorSummary;

    }[/tt]

Зачем плохому людей учишь? Вот намного проще и идеологически правильней:

1. В модели:



	public function rules()


	{


		return array(


			...


			array('dat','yourDataValidator'),


			...


		);


	}





	public function yourDataValidator()


	{


		//Здесь пишем код валидатора даты


	}


А вообще есть CTypeValidator, в котором type может принимать значение date с настраиваемым форматом, так что можно даже свой валидатор не писать, а ограничиться использованием того что идет в комплекте с фреймворком.

2. В контроллере:



	public function actionAdd()


	{


		$new=new New;


		if(isset($_POST['New']))


		{


			$new->attributes=$_POST['New'];


			if($new->save()) //ВОТ ТУТ ВАЛИДАЦИЯ, проверка $new->hasErrors() была бы лишней


				$this->redirect(array('show','id'=>$new->id));


		}


		$this->render('create',array(


			'new'=>$new,


		));


	}


3. В представлении:



<?php echo CHtml::errorSummary($new); ?> //В случае если есть ошибки они все тут выведутся, и не нужно вызывать в представлении условие и передавать туда лишнюю переменную $errorSummary


P.S. Метод beforeValidate в модели вообще то не для валидации предназначен. А для работы с датой есть компонент CDateFormatter, вызывается Yii::app()->dateFormatter. Он подключается фреймворком по умолчанию, а поэтому грех его не использовать  ;)

Я бы еще не стал в модели использовать обращение к массиву POST

isset($_POST['News']['dat'])

источник данных может поменяться - тогда придется переписывать и модель…

Quote

Зачем плохому людей учишь?
  • то о чем пишешь ты годится для модели формы,

  а не для модели базы (вернее таблицы)

Quote

P.S. Метод beforeValidate в модели вообще то не для валидации предназначен. А для работы с датой есть компонент CDateFormatter, вызывается Yii::app()->dateFormatter. Он подключается фреймворком по умолчанию, а поэтому грех его не использовать  ;)
  • мне не надо переделать дату в локальный языковый формат, а надо

  переделать в формат базы данных

Quote

- то о чем пишешь ты годится для модели формы,

  а не для модели базы (вернее таблицы)

Это годится для любого типа дочерних классов CModel, в частности для CActiveRecord, CFormModel. Смотри API перед тем, как утверждать что то на 100%

Quote

- мне не надо переделать дату в локальный языковый формат, а надо

  переделать в формат базы данных

CDateFormatter позволяет производить любые манипуляции с датой методом format(), в том числе и перевод в формат БД.

Quote

Это годится для любого типа дочерних классов CModel, в частности для CActiveRecord, CFormModel. Смотри API перед тем, как утверждать что то на 100%

блин, документация это одно, а жись это другое.

пришли работающий пример

Quote

CDateFormatter позволяет производить любые манипуляции с датой методом format(), в том числе и перевод в формат БД.

почему именно так, разве не проще [tt]date('Y-m-d') [/tt]