Intereting Posts
присвоение $ _GET и $ _POST одной переменной Определение URL-адреса объекта данных – Silverstripe 3.1 Как обновить / расширить токены доступа к Facebook с помощью PHP? Предупреждать пользователя, если сеанс истекает, возможность возобновления сеанса Вызов двух хранимых процедур в mysqli вызывает ошибку «Commands out of sync» Плагины для коротких кодов для собственных пользовательских cms, таких как плагины для коротких сообщений WordPress php ssh2_exec не выполняет команду su Отправка запроса POST локальному хосту, данные, полученные, но не отображающиеся на веб-странице PHP и запланированные задачи PHP-черты: как разрешить конфликт имен свойств? Textarea и текст ввода редактируются при использовании плагина HTML2PDF cURL Отправка полей POST после загрузки страницы (curl_exec)? Развернуть строку PHP новой строкой Magento – Пользовательский платежный модуль Обнаруживать при нажатии ссылки, открыть в новом кадре

Zend Form Edit и Zend_Validate_Db_NoRecordExists

Я медленно наращиваю свои навыки Zend, создавая некоторые полезные сайты для собственного использования. Я использую Zend Forms и Form validation, и до сих пор был счастлив, что я понимаю способ Zend делать вещи. Однако я немного смущен тем, как использовать Zend_Validate_Db_NoRecordExists () в контексте формы редактирования и поле, которое сопоставляется столбцу базы данных, которое должно быть уникальным.

Например, используя эту простую таблицу

TABLE Test ( ID INT AUTO_INCREMENT, Data INT UNIQUE ); 

Если бы я просто добавлял новую строку в Table Test, я мог бы добавить валидатор в элемент формы Zend для поля Data как таковой:

 $data = new Zend_Form_Element_Text('Data'); $data->addValidator( new Zend_Validate_Db_NoRecordExists('Test', 'Data') ) 

При проверке формы этот валидатор проверяет, что содержимое элемента данных еще не существует в таблице. Таким образом, вставка в Test может идти вперед, не нарушая поля Data data UNIQUE.

Однако при редактировании существующей строки таблицы Test ситуация меняется. В этом случае валидатору необходимо проверить, что значение элемента соответствует одному из двух условий взаимоисключающих условий:

  1. Пользователь изменил значение элемента, и новое значение в настоящее время не существует в таблице.

  2. Пользователь не изменил значение элемента. Таким образом, значение в настоящее время существует в таблице (и это нормально).

В документах по проверке Zend говорится о добавлении параметра в средство проверки NoRecordExists () с целью исключения записей из процесса проверки. Идея состоит в том, чтобы «проверить таблицу на поиск подходящих строк, но игнорировать любые обращения, в которых поле имеет это конкретное значение». Такой пример использования – это то, что необходимо для проверки элемента при редактировании таблицы. Псевдокод для этого в 1.9 подобен этому (на самом деле я получил это из исходного кода 1.9 – я думаю, что текущие документы могут быть неправильными):

 $data = new Zend_Form_Element_Text('Data'); $data->addValidator( new Zend_Validate_Db_NoRecordExists('Test', 'Data', array ('field'=>'Data', 'Value'=> $Value) ); 

Проблема в том, что значение, которое должно быть исключено ($ Value), привязывается к валидатору в момент его создания (также при создании экземпляра формы). Но когда форма редактирует запись, это значение должно быть привязано к содержимому поля $ data, когда форма была сначала заполнена данными – IE – значение Data, первоначально прочитанное из строки Test table. Но в типичных шаблонах Zend форма создается и заполняется двумя отдельными шагами, что исключает привязку значения exclude к требуемому значению элемента.

Следующие кодовые обозначения Zend psuedo отмечают, где мне нужно привязать значение Value к NoRecordExists () для проверки подлинности (и обратите внимание, что это общий шаблон контроллера Zend):

 $form = new Form() if (is Post) { $formData = GetPostData() if ($form->isValid($formData)) { Update Table with $formData Redirect out of here } else { $form->populate($formData) } } else { $RowData = Get Data from Table $form->populate($RowData) <=== This is where I want ('value' => $Value) bound } 

Я мог бы подклассифицировать Zend_Form и переопределить метод populate (), чтобы сделать однократную вставку валидатора NoRecordExists () в начальном образовании, но это кажется огромным взломом для меня. Поэтому я хотел знать, что думают другие люди, и есть ли какая-то модель, уже записанная, которая решает эту проблему?

Изменить 2009-02-04

Я думал, что единственное достойное решение этой проблемы – написать пользовательский валидатор и забыть о версии Zend. Моя форма имеет идентификатор записи как скрытое поле, так что, учитывая имена таблиц и столбцов, я мог бы обработать некоторый SQL для проверки на уникальность и исключить строку с идентификатором такого типа. Конечно, это заставило меня задуматься о том, как я привяжу форму к слою дБ, который должна скрывать модель.

Related of "Zend Form Edit и Zend_Validate_Db_NoRecordExists"

Вот как это делается:

  1. Я ваш FORM, вы добавляете этот валидатор (например, поле электронной почты):
 $email->addValidator('Db_NoRecordExists', true, array('table' => 'user', 'field' => 'email')); 
  1. Не добавляйте специальное сообщение об ошибке для этого, так как после этого он не работал для меня, например:
 $email->getValidator('Db_NoRecordExists')->setMessage('This email is already registered.'); 

  1. В контроллере добавьте следующее:
 /* Don't check for Db_NoRecordExists if editing the same field */ $form->getElement('email') ->addValidator('Db_NoRecordExists', false, array('table' => 'user', 'field' => 'email', 'exclude' => array ('field' => 'id', 'value' => $this->request->get('id')))); And after this you do verifications, eg: if ($this->getRequest()->isPost()) { if($form->isValid($this->getRequest()->getPost())) { .... 

Это оно!

Это также будет работать:

 $this->addElement('text', 'email', array( 'label' => 'Your email address:', 'required' => true, 'filters' => array('StringTrim'), 'validators' => array( 'EmailAddress', array('Db_NoRecordExists', true, array( 'table' => 'guestbook', 'field' => 'email', 'messages' => array( 'recordFound' => 'Email already taken' ) ) ) ) )); 

После рассмотрения подавляющего ответа я решил, что я собираюсь использовать специальный валидатор

Посмотрите на это: ответ, поднятый мной и хорошо разрешенный Дики

 private $_id; public function setId($id=null) { $this->_id=$id; } public function init() { ..... if(isset($this->_id)){ $email->addValidator('Db_NoRecordExists', false, array('table' => 'user', 'field' => 'email','exclude' => array ('field' => 'id', 'value' => $this->_id) )); $email->getValidator('Db_NoRecordExists')->setMessage('This email is already registered.'); } 

Теперь вы можете использовать:

 $form = new Form_Test(array('id'=>$id)); 

Вы можете просто вызвать $form->getElement('input')->removeValidator('Zend_Validator_Db_NoRecordExists'); вместо предоставления исключения.

Я только что попробовал этот пример для уникальности email address и он отлично работает с данными ниже:

1] В моей форме:

 // Add an email element $this->addElement('text', 'email', array( 'label' => 'Email :', 'required' => true, 'filters' => array('StringTrim'), 'validators' => array( 'EmailAddress', ) )); 

Вот что-то особенное, что мне нужно было добавить для unique email address для работы:

  $email = new Zend_Form_Element_Text('email'); $email->addValidator('Db_NoRecordExists', true, array('table' => 'guestbook', 'field' => 'email')); 

2] В моем контроллере:

 $form->getElement('email') ->addValidator('Db_NoRecordExists', false, array('table' => 'guestbook', 'field' => 'email', 'exclude' => array ('field' => 'id', 'value' => $request->get('id')))); if ($this->getRequest()->isPost()) { if ($form->isValid($request->getPost())) { 

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

благодаря