Известное дело — разработку любого веб-приложения можно поделить на этапы, а сами этапы — на типовые задачи. Одной из наиболее часто встречающихся типовых задач является работа с формами. Каждый раз, когда программисту приходится сталкиваться с ней, можно словить некоторое уныние, если надоевшая рутина не оформлена подобающим образом. Прежде, чем уйти под кат, покажу вам, как реализована работа с формами в cogear:
$this->form->set('add-comments')
->input('subject',array('validation' => 'required|max_length[80]'))
->editor('body',array('validation'=>'required|min_length[5]'))
->buttons('send');
if($result = $this->form->result()){
  if($this->form->save('comments',$result)){
    redirect('/node_url');
  }
}
$this->form->compile();


* This source code was highlighted with Source Code Highlighter.


Выше показана наиболее простая, но очень эффективная форма работы, простите за каламбур, с формами.

Один код в ответе за все


Нет нужды создавать отдельные методы контроллера для ловли данных — все функции на себя берет один кусочек кода.

Первым делом мы задаем id формы, который пригодится нам при использовании хуков или же при ином деле.
$this->form->set('add-comments')

* This source code was highlighted with Source Code Highlighter.

После этого цепочкой задаются элементы и их параметры, а также кнопки формы.
    // Добавляем поле типа "текст"
    ->input('subject', array('validation' => 'required|max_length[80]'))
    // Добавляем поле типа "редактор"
    ->editor('body',array('validation'=>'required|min_length[5]'))
    // Задаем кнопки
    ->buttons('send');

* This source code was highlighted with Source Code Highlighter.


Сразу же небольшое отступления для ответов на возможные вопросы:
1. При формировании вывода label к элементу берется на основании указанной, либо общей переменной перевода (общие хранятся в разделе edit).
Допустим, у нас есть языковой файл, в котором заданы названия и описания наших полей.
[my_form]
subject = "Заголовок комментария"
subject_description = "Укажите заголовок комментария. Не более 80 символов."
body = "Текст"
body_description = "Текст комментария не должен быть слишком коротким – от 5 символов и больше, пожалуйста."



// Функция-ярлык для задания текущего раздела классу i18n
d('my_form');
$this->form->set('add-comments')
->input('subject', array('validation' => 'required|max_length[80]'))
->editor('body',array('validation'=>'required|min_length[5]'))
->buttons('send');
if($result = $this->form->result()){
  if($this->form->save('comments',$result)){
    redirect('/node_url');
  }
}
$this->form->compile();


* This source code was highlighted with Source Code Highlighter.


Есл�� перед выводом формы задать текущий раздел переводов, то на выходе мы получим форму следующего вида:


2. Обработка ошибок идет автоматически на базе указанных правил. Никаких дополнительных действий с вашей стороны не требуется.


Работа с ошибками


Вы отправляете форму, и если валидация не проходит, форма выводится по-новой с отображением ошибок.


Можно усовершенствовать форму, добавив валидацию на JavaScript до ее отправки.
// Функция-ярлык для задания текущего раздела классу i18n
d('my_form');
$this->form->set('add-comments')
->input('subject', array('validation' => 'required|max_length[80]','js_validation'=>'required|length[5,80]'))
->editor('body',array('validation'=>'required|min_length[5]','js_validation'=>'required|length[5,-1]'))
->buttons('send');
if($result = $this->form->result()){
  if($this->form->save('comments',$result)){
    redirect('/node_url');
  }
}
$this->form->compile();

* This source code was highlighted with Source Code Highlighter.


Обнов��в страницу увидим, что теперь скрипты не дадут нам отправить форму до того, как она будет заполнена корректно.


Если вы уже задались вопросом, почему отличаются правила для пре- и пост-валидации, отвечаю:
— Для пре-валидации используется доработанный класс MooTools.Floor Form Check.
— Для пост-валидации используется доработанная библиотека CodeIgniter (который лежит в основе движка).

Напоследок приведу более развернутый пример — с упрощенным созданием/редактированием топиков.

class Index extends Controller{
  …
  /**
   * Создание и редактирование топиков.
   *
   * @param  int    $id    id топика
   * @return  void
   */
  function createdit($id = FALSE){
    // Функция-ярлык для задания текущего раздела классу i18n
    d('node_edit');
    // Определяем, существует ли топик
    if($id && $node = $this->db->get_where('nodes',array('id'=>$id))->row()){
      /*
       * Если топик существует задаем иной заголовок страницы
       * Строка перевода выглядит следующим образом
       * …
       * edit = "Редактирование топика '%s'"
       * …
       */
      title(t('edit',$node->name));  
    }
    else {
      // Можно указать раздел перевода и явным образом
      title(t('node_edit create'));  
    }
    // Задаем имя формы
    $this->form->set('node-createdit')
    // Добавляем поле типа "текст"
    ->input('subject', array('validation' => 'required|max_length[80]','js_validation'=>'required|length[-1,80]'))
    // Добавляем поле типа "редактор"
    ->editor('body',array('validation'=>'required|min_length[5]','js_validation'=>'required|length[5,-1]'))
    // Задаем кнопки
    // Если топик не сущесвует или мы не в режим редактирования, то будет отображена кнопка "Сохранить" вместо "Создать".
    ->buttons(empty($node) ? 'create' : 'save');
    
    // Если топик существует — заполняем форму его значениями
    if(!empty($node)){
      $this->form->set_values($node);  
    }
    // Ловим результат обработки формы
    if($result = $this->form->result()){
      // Если топик существует — обновляем его
      if(!empty($node) && $this->form->update('nodes',$result,array('id'=>$node->id)){
        redirect('/nodes/'.$node->id);
      }
      // Создаем новый топик
      elseif($this->form->save('comments',$result)){
        redirect('/'.$this->form->insert_id);
      }
    }
    // Выводим форму
    $this->form->compile();
  }
  …
}


* This source code was highlighted with Source Code Highlighter.


Разумеется, в данном топик показаны самые простые примеры работы с формами в cogear — для простоты восприятия и наглядности.
Наша реализация работы с формами хорошо себя зарекомендовала за последний год — она позволяет сократить время на разработку типовых задача ввода и обработки информации до минимума. Да, в кому-то она может показаться не идеальной, но

Надеюсь, вам понравился краткий экскурс в собственные задумки.

Если есть вопрос — задавайте, если хотите продолжения — будет и оно.

Как вы организуете работу с формами?