O ZendFramework possui muitos validators prontos, porém algumas vezes é necessário criar alguns específicos, como por exemplo a validação de CPF, que por padrão não tem no Framework. Mas e como fazer isso? Descreverei a seguir:
Primeiro vamos criar o Validate no caminho lybrary/My/Validate/Cpf.php
<?php
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
class My_Validate_Cpf extends Zend_Validate_Abstract {
const NOT_CPF = 'notCpf';
protected $_messageTemplates = array(
self::NOT_CPF => "'%value%' não é um CPF válido.",
);
protected $_numericOnly;
/**
* Se o CPF for apenas numerico 12345678909 então $numbersOnly é true
* Se não, 123.456.789-09
* @param bool $numbersOnly
*/
public function __construct($numbersOnly = false)
{
$this->_setNumericOnly($numbersOnly);
}
/**
* Sets $_numericOnly
* @param bool $bool
*/
private function _setNumericOnly($bool = false){
$this->_numericOnly = $bool;
if($this->_numericOnly === true){
$this->_regexp = '/^(d){11}$/';
}
else{
$this->_regexp = '/^(d){3}(.d{3}){2}-(d){2}$/';
}
return $this;
}
/**
*
* @param mixed $value
* @return boolean
* @throws Zend_Valid_Exception If validation of $value is impossible
* @see Zend_Validate_Interface::isValid()
*/
public function isValid($value) {
// checks regexp, first and second validation Digit
if ( preg_match($this->_regexp, $value)
&& $this->_checkDigitOne($this->_removeNonDigits($value))
&& $this->_checkDigitTwo($this->_removeNonDigits($value))
){
return true;
}
$this->_setValue($value);
$this->_error(self::NOT_CPF);
return false;
}
/**
*
* @param string $value
* @return bool
*/
private function _checkDigitOne($value)
{
$multipliers = array(10,9,8,7,6,5,4,3,2);
return $this->_getDigit($value, $multipliers) == $value{9};
}
/**
*
* @param string $value
* @return bool
*/
private function _checkDigitTwo($value)
{
$multipliers = array(11,10,9,8,7,6,5,4,3,2);
return $this->_getDigit($value, $multipliers) == $value{10};
}
/**
*
* @param string $value
* @param array(int) $multipliers
* @return int
*/
private function _getDigit($value, $multipliers)
{
foreach($multipliers as $key => $v){
$sum += $value{$key} * $v;
}
$digit = $sum % 11;
if ($digit < 2) {
$digit = 0;
}else{
$digit = 11 - $digit;
}
return $digit;
}
/**
*
* @param string $value
* @return string
*/
private function _removeNonDigits($value)
{
return preg_replace('/D/', '', $value);
}
}
?>
O validate já está criado e a forma de usa-lo é bem semelhante aos demais validators, vamos então criar o formulário no caminho: application/forms/ValidaCpf.php.
<?php
class Application_Form_ValidaCpf extends Zend_Form {
public function init()
{
Zend_Dojo::enableForm($this);
}
public function __construct($options = null) {
parent::__construct ($options);
//definicoes do campo CPF
//$cpf = new Zend_Form_Element_Text('cpf');
$cpf = new Zend_Dojo_Form_Element_TextBox('cpf');
$cpf->setLabel('CPF: ')
->setTrim(true)
->setRequired(true)
->addFilter('Alnum')
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty', true, array('messages' => array('isEmpty' => 'Preencha este campo antes de prosseguir!')))
->addPrefixPath('My_Validate', 'My/Validate/', 'validate')
->addValidator('Cpf', true, array(true));
//definicoes do botao de enviar
$enviar = new Zend_Dojo_Form_Element_SubmitButton('enviar');
$enviar->setLabel('Enviar');
$this->addElements(array($cpf, $enviar));
}
}
?>
Instancie o Form onde ele será utilizado e pronto, no caso aqui para exemplo será utilizado no IndexController.php na action validaCpf no caminho: application/controllers/IndexController.php
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
Zend_Dojo::enableView($this->view);
}
public function indexAction()
{
// action body
}
public function validaCpfAction() {
$form = new Application_Form_ValidaCpf(array(
'action' => $this->view->baseUrl().'/index/valida-cpf',
'method' => 'post'));
$this->view->form = $form;
//se o formulario foi enviado via post
if ($this->getRequest()->isPost()) {
//recupera os dados enviados
$formData = $this->getRequest()->getPost();
//se o formulario foi preenchido corretamente
if ($form->isValid($formData)) {
echo 'valido';
}else {
//popula os campos com os dados preenchidos
$form->populate($formData);
}
}
}
?>
e por fim a view no caminho: application/views/scripts/index/valida-cpf.phtml
Validação de CPF
<?php
echo $this->form;