В этой статье я покажу решение распространенной проблемы, которая возникает, когда разработчику необходимо создать неанглийский веб-сайт или приложение, основанное на Zend Framework. Как пометить поле Zend_Form
которое является элементом Zend_Form_Element
как недействительное, показывающее одно или несколько пользовательских сообщений об ошибках? Проблема в основном вызвана нативными неинтуитивными методами класса Zend_Form_Element
которые я объясню более подробно. (Обратите внимание, что проблема и решение, обсуждаемое здесь, действительно для Zend Framework версии 1.12 и ниже.)
Разработка примера
Допустим, у вас есть форма с разными полями, и вы учитываете только одно из них, например, поле ввода текста, которое позволяет пользователю вводить свое имя. Валидаторы, которые вы можете использовать, разные, но для примера мы ограничим длину имени, и в нем будут только алфавитные символы и пробелы. Говоря на языке Zend Framework, мы будем использовать Zend_Validate_StringLength
и Zend_Validate_Alpha
соответственно.
Как вы, возможно, уже знаете, Zend Framework принадлежит американской компании Zend, поэтому все сообщения, которые она показывает, представлены на английском языке. Поведение платформы по умолчанию — отображать одно или несколько сообщений об ошибках для каждого валидатора, нарушенного пользовательским вводом. Таким образом, для тех, кто создает неанглоязычный веб-сайт, есть два варианта, чтобы сообщения были доступны для чтения всем пользователям: перевести каждое сообщение об ошибке платформы или объяснить в одном или нескольких сообщениях, что ввод недопустим, и показать предложения для вставки. принятая стоимость. Первый вариант слишком сложен, особенно для небольших и средних проектов, поэтому я покажу, как использовать второй вариант.
Для простоты мы установим одно специальное сообщение: «Ввод неверен. Значение должно содержать только буквенные символы и пробелы, а его длина должна составлять от 3 до 50 символов ».
Код
Я покажу код, который мы будем использовать в статье. Во-первых, это форма, которая содержит поле ввода имени и валидаторы, необходимые для проверки данных.
<?php class Application_Form_User extends Zend_Form { public function init() { // create the field $element = new Zend_Form_Element_Text("name"); $element->setLabel("Name"); // set the validators $element->setValidators(array( new Zend_Validate_Alpha(true), new Zend_Validate_StringLength( array("min" => 3, "max" => 50)) )); $element->setRequired(); // add the element to the form $this->addElement($element); // add a submit button $element = new Zend_Form_Element_Submit("submit"); $element->setLabel("Submit"); $this->addElement($element); } }
В контроллере мы проверим правильность поля и будем действовать соответственно. Обычно вы не будете использовать IndexController
и, вероятно, у вас есть эта проверка в конкретном контроллере. Во всяком случае, чтобы упростить пример, я буду его использовать.
<?php class IndexController extends Zend_Controller_Action { public function init() { } public function indexAction() { $form = new Application_Form_User(); if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) { $this->view->message = "Valid input"; } else { $this->view->form = $form; } } }
Используемый вид довольно прост; это только показывает сообщение и форму.
<?php if (isset($this->message)) { echo $this->message; } if (isset($this->form)) { echo $this->form; }
Приведенный выше исходный код без каких-либо правил CSS будет отображаться так:
Более того, если вы введете недопустимое значение «88» в поле «Имя», вы увидите сообщения:
Анализ методов фреймворка
Хороший вопрос, который нужно задать: есть ли уже методы, позволяющие справиться с такой ситуацией? Ответ почти . Я имею в виду, что есть методы, но они не всегда работают так, как вы ожидаете (по крайней мере, как я ожидаю). Способы управления сообщениями об ошибках:
-
setErrors(array $messages)
-
setErrorMessages(array $messages)
Метод setErrors()
имеет только один параметр, который является массивом, и использует его элементы в качестве сообщений для отображения в случае неверного ввода. Пример его использования:
<?php // set the custom message in the case of an error $element->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));
Этот метод, а также отображение заданной строки (строк) также помечает поле как недействительное.
Его можно использовать два раза в логике приложения, но в обоих случаях он имеет поведение, которое бесполезно для нашей цели. Первый — при создании элемента формы init()
метод init()
). В этом случае сообщение отображается, когда форма была загружена и до того, как пользователь вставил какие-либо данные. Довольно неприятно. В этом случае соответствующая часть кода изменяется следующим образом:
<?php // set the validators $element->setValidators(array( new Zend_Validate_Alpha(true), new Zend_Validate_StringLength( array("min" => 3, "max" => 50)) )); $element->setRequired(); // set the custom message in the case of an error $element->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));
Второй раз происходит после того, как информация была отправлена во время обычной проверки данных в контроллере. В случае ошибки пользовательское сообщение добавляется к стандартному сообщению. В этом случае indexAction()
IndexController
изменяется следующим образом:
<?php public function indexAction() { $form = new Application_Form_User(); if ($this->getRequest()->isPost()) { // If the input of the user is valid, set the success // message. Otherwise, set the custom errors and show // the form again. if ($form->isValid($this->getRequest()->getPost())) { $this->view->message = "Valid input"; } else { $form->getElement("name")->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters.")); $this->view->form = $form; } } else { $this->view->form = $form; } }
Как и setErrors()
, метод setErrorMessages()
принимает в качестве параметра массив строк, которые будут показаны пользователю в случае неправильного ввода. Пример его использования:
<?php $element->setErrorMessages(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));
Эта строка кода по-прежнему не решает проблему, поскольку она будет отображать одно и то же сообщение об ошибке для каждого неудовлетворенного условия или не будет иметь никакого эффекта. Если показанная строка используется в методе init()
, так же, как показано для setErrors()
, в случае ошибки пользовательское сообщение будет отображаться столько раз, сколько условий нарушено пользовательским вводом. Если строка вставляется во время обычной проверки данных в контроллере, как описано выше, никакого эффекта не будет. Это означает, что пользовательское сообщение не будет отображаться, и платформа будет показывать только сообщения по умолчанию.
Раскрытие решения
Теперь важно понять, когда и как вставить пользовательское сообщение, чтобы у пользователя было сравнение и предложение о том, какие значения принимаются. Определенно, когда лежит в создании поля внутри формы init()
метод init()
) и как происходит из-за объединения метода setErrorMessages()
и использования свойства валидаторов Zend Framework, называемого breakChainOnFailure()
, Последнее позволяет нам остановить процесс проверки при первом сбое. Если мы настроим пять валидаторов, но первый из них потерпит неудачу, остальные четыре не будут использованы.
Чтобы использовать это свойство, используя наименьшее возможное количество строк кода, я немного изменю код, который я проиллюстрировал в начале. Я добавлю к методу init()
строку кода, которая использует метод setErrorMessages()
, и я воспользуюсь одной из возможных конфигураций ввода, принятых setValidators()
которая ожидает массив массивов. Массив, содержащийся в главном, может иметь максимум три параметра:
- Строка (обязательная) для указания валидатора для пользователя.
- Логическое значение (необязательно, по умолчанию его значение равно
false
), чтобы указать, должна ли структура нарушать проверку при первом сбое или нет. Таким образом, этот параметр устанавливает значение свойстваbreakChainOnFailure
которое поможет нам в достижении нашей цели. - Массив опций (необязательный, по умолчанию пустой массив), различный для каждого выбранного валидатора
Использование второго параметра, переданного как true для каждого из валидаторов, которые вы хотите использовать, является обязательным.
Согласно тому, что мы видели до сих пор, результирующий код выглядит так:
<?php class Application_Form_User extends Zend_Form { public function init() { // create the field $element = new Zend_Form_Element_Text("name"); $element->setLabel("Name"); // set the validators $element->setValidators(array( array("Alpha", true, array("allowWhiteSpace" => true)), array("StringLength", true, array( "min" => 3, "max" => 50)) )); $element->setRequired(); // set the custom message in the case of an error $element->setErrorMessages(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters.")); // add the element to the form $this->addElement($element); // add a submit button $element = new Zend_Form_Element_Submit("submit"); $element->setLabel("Submit"); $this->addElement($element); } }
Вывод
Используя приведенный выше код, форма будет показывать только пользовательское сообщение при неправильном вводе … именно то, что мы хотели! Если вам нужно использовать больше сообщений, например предложения в несколько этапов, просто добавьте больше строк в массив, используемый для setErrorMessages()
.
Изображение через Fotolia