CakePHP : Manual11/Validation

Верификация данных

Создание настраиваемых правил верификации поможет убедиться, что данные модели соответствуют рабочим правилам приложения, такие как пароли, которые могут быть длинною не более восьми символов, имена пользователей, которые должны содержать только буквы и т.д.

Первый шаг к проверке данных это создания правил верификации в модели. Чтобы сделать это, воспользуйтесь масивом Model::validate в определении модели, например:
/app/models/user.php
<?php
class User extends AppModel
{
   var 
$name 'User';

   var 
$validate = array(
      
'login' => '/[a-z0-9\_\-]{3,}$/i',
      
'password' => VALID_NOT_EMPTY,
      
'email' => VALID_EMAIL,
      
'born' => VALID_NUMBER
   
);
}
?>


Верификация определяется Perl-совместимыми регулярными выражениями, некоторые из них уже определены в /libs/validators.php. Это:

Если будут присутствовать еще какие-то верификации в определении модели (например, в масиве $validate), они будут проанализированы и проверены во время сохранений (например, в методе Model::save()). Если нужно проверить данные непосредственно, используйте Model::validates() (возвращает false в случае некорректных данных) и Model::invalidFields() (возвращает масив сообщений об ошибках).

Но обычно данные подразумеваются в коде контроллера. Следующий пример демонстрирует как создать действие управления формой:

Действие управления формой в /app/controllers/blog_controller.php
<?php
class BlogController extends AppController {

   var 
$uses = array('Post');

   function 
add ()
   {
      if (empty(
$this->data))
      {
         
$this->render();
      }
      else
      {
         if(
$this->Post->save($this->data))
         {
             
//все ок, проверено
         
}
         else
         {
            
//Опасность, Уилл Робинсон. Ошибки верификации.
            
$this->set('errorMessage''Please correct errors below.');
            
$this->render();
         }
      }
   }
}
?>


Отображение, используемое этим действием может выглядить так:

Отображение формы add в /app/views/blog/add.thtml
<h2>Add post to blog</h2>
<form action="<?php echo $html->url('/blog/add')?>" method="post">
    <div class="blog_add">
        <p>Title:
            <?php echo $html->input('Post/title', array('size'=>'40'))?>
            <?php echo $html->tagErrorMsg('Post/title''Title is required.')?>
        </p>
        <p>Body
            <?php echo $html->textarea('Post/body'?>
            <?php echo $html->tagErrorMsg('Post/body''Body is required.')?>
        </p> 
        <p><?=$html->submit('Save')?></p>
    </div>
</form>


Controller::validates($model[, $model...]) используется для настраиваемой проверки в модели. Метод Controller::validationErrors() возвращает все ошибки, их можно отобразить используя tagErrorMsg().

Если вы хотите выполнить каку-то особую верификацию отдельно от обычной верификации Cake, вы можете использовать функцию invalidate() со своей модели, чтобы пометить поле как ошибочное. Представьте, что вы хотите показать ошибку в форме если пользователь пытается создать имя которое уже существует в системе. Поскольку вы просто не можете узнать этого стандартными средствами Cake, вам понадобится провести собственную верификацию и пометить поле как неверное для обычной верификации Cake.

Контроллер может выглядить так:
<?php

class UsersController extends AppController
{
    function 
create()
    {
        
// Проверяет были ли посланные данные из формы
        
if (!empty($this->data['User']))
        {
            
//Проверяет существует ли пользователь с таким именем
            
$user $this->User->findByUsername($this->data['User']['username']);

            
// Помечаем поле как неверное, чтобы запустить сообщение об ошибке HTML Хелпера
            
if (!empty($user['User']['username']))
            {
                
$this->User->invalidate('username');//заполняем tagErrorMsg('User/username')
            
}

            
// Пробуем записать как обычно, не должно работать если поле было помечено как неверное.
            
if($this->User->save($this->data))
            {
                
$this->redirect('/users/index/saved');
            }
            else
            {
                 
$this->render();
            }
        }
    }
}

?>