Валидатор HTML-форм

от автора

Доброго времени суток уважаемый %username%.

Каждый программист хоть раз в своей жизни сталкивался с унаследованным кодом. Иногда такой код вызывает реакцию: «Что это за дрянь|лапша|говнокод, давайте его перепишем».

Так произошло и с проектом к которому я присоединился. 200-300 строчные методы, дублирование кода, процедурный подход вместо использования ООП не вызывали ни каких положительных эмоций. К счастью ПМ оказался очень адекватным человеком и не отмахнулся от просьбы выделить время на рефакторинги. Один из таких рефакторингов в итоге вылился в плагин валидации HTML-форм, которым я и хочу поделиться.

Причиной для создания этого плагина послужил код вида:

if($this->request->data['Model']['field'] > 0) { 	$this->Session->setFlash(«message»); 	$this->redirect($this->referer()); } if($this->request->data['Model']['field'] == «string») { 	$this->Session->setFlash(«message»); 	$this->redirect($this->referer()); } 

Которым изобиловали экшены. В некоторых экшенах количество аналогичных конструкций доходило до десятка. В итоге логика экшена полностью терялась за множественными ifами. Часто «коллекции» этих конструкций дублировались в нескольких экшенах и даже контроллерах. Те кто использует CakePHP, знают об удобном валидаторе полей моделей. В моем случае напрямую его не всегда удавалось задействовать, в формах передавались поля которые не ассоциировались с полями таблиц в моделях.

После рассмотрения вариантов рефакторинга для этого кода, было принято решение о создании класса-валидатора для передаваемых в формах данных. В качестве базы для него был использован класс ModelValidator. К сожалению его архитектура не позволила использовать наследование. Пришлось воспользоваться старым добрым копи-пастом.

В итоге получился класс, который позволяет проверять ассоциативные массивы вида:

array( 'Model' => array(field_list))  

используя всю мощь класса Validation.

Примеры использования

HTML — форма:

	echo $this->Form->create('Model'); 	echo $this->Form->input('first_field', array('type' => 'text')); 	echo $this->Form->input('second_field', array('type' => 'text)); 	echo $this->Form->end(); 

Класс формы:

App::uses('Form', 'Forms.Lib/Form');  class ExampleForm extends Form { 	public $model = 'Example';  	public $fields = array( 		'first_field' => array( 			'type' => 'text', 		), 		'second_field' => array( 			'type' => 'text', 		) 	);  	public $validate = array( 		'second_field' => array( 			'isActive' => array( 				'rule' => 'isActive', 				'message' => "Is fields not active!" 			), 		), 		'first_field' => array( 			'aboveZero' => array( 				'rule' => 'aboveZero', 				'message' => "Number must be greater than 0", 			), 		), 	);  	/** 	 * @return bool 	 */ 	public function isActive(){ 		if(isset($this->options['user_id'])) { 			return false; 		} 		return (bool)$this->data[$this->model]['second_field']; 	}  	/** 	 * @return bool 	 */ 	public function aboveZero() { 		return (is_numeric($this->data[$this->model]['first_field']) && ($this->data[$this->model]['first_field'] > 0)); 	} } 

Использование класса ExampleForm для валидации данных формы:

class ExamplesController extends AppController { 	public $name = 'Examples'; 	public $uses = array( 		'Example', 	);  	public $components = array( 		'Forms.FormValidator' 	);  	public $forms = array( 		'ExampleForm', 	);  	/** 	 * Example validation html-form data in $this->request->data 	 */ 	public function example() { 		if ($this->ExampleForm->validates($this->request->data)) { 			echo 'true validations'; 		} else { 			echo 'false validation'; 		} 	} } 

Использование класса ExampleForm для валидации ассоциативного массива:

	public function example2() { 		$data = array( 			'Example' => array( 				'first_field' => 0, 				'second_field' => true 			) 		); 		if ($this->ExampleForm->validates($data)) { 			echo 'true validations'; 		} else { 			echo 'false validation'; 		} 	} 

Использование класса ExampleForm для валидации ассоциативного массива, с передачей дополнительных данных для проверок:

	public function example3() { 		$data = array( 			'Example' => array( 				'first_field' => 0, 				'second_field' => true 			) 		); 		$this->ExampleForm->addOptions(array('user_id' => $this->Auth->user('id'))); 		if ($this->ExampleForm->validates($data)) { 			echo 'true validations'; 		} else { 			echo 'false validation'; 		} 	} 

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

Код плагина на github.

ссылка на оригинал статьи http://habrahabr.ru/post/197928/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *