who gives me a hand to create a custom validator for Zend Framework, which checks that a date is in to a range?
Example:
dateGT = 2011-09-05
dateLT = 2011-07-05
if the form field is set to: dateFieldForm = 2011-08-15 I expect the validator returns true!
and if the form field is set to: dateFieldForm = 2011-10-15 I expect the validator returns false!
I write a test phpunit for class by venimus. I hope it can help someone.
class Validate_DateCompareTest extends PHPUnit_Framework_TestCase {
public function dataForTest()
{
return array(
array('2011-06-05', '2011-06-01', '2011-06-10', true), //between dates
array('2011-06-10', '2011-06-01', '2011-06-10', true), //between dates
array('2011-06-01', '2011-06-01', '2011-06-10', true), //between dates
array('2011-06-15', '2011-06-01', '2011-06-10', false), //between dates
array('2011-05-30', '2011-06-01', '2011-06-10', false), //between dates
array('2011-06-01', '2011-06-01', null, true), //exact match
array('2011-06-15', '2011-06-01', null, false), //exact match
array('2011-05-30', '2011-06-01', null, false), //exact match
array('2011-06-02', '2011-06-01', true, true), //not later
array('2011-06-01', '2011-06-01', true, false), //not later
array('2011-05-30', '2011-06-01', true, false), //not later
array('2011-05-30', '2011-06-01', false, true), //not earlier
array('2011-06-01', '2011-06-01', false, false), //not earlier
array('2011-06-10', '2011-06-01', false, false), //not earlier
);
}
/**
* @dataProvider dataForTest
* @param $value
* @param $token
* @param $compare
* @param $expected
* @return void
*/
public function testDateCompare($value, $token, $compare, $expected)
{
/** @var $validate My_Validate_DateCompare */
$validate = new My_Validate_DateCompare($token, $compare);
$this->assertEquals(
$expected,
$validate->isValid($value),
"value: $value -- token: $token -- compare: $compare"
);
}
}
this class has been really helpful to me thanks again!
Sorry, large code ahead:
<?php
/** @see Zend_Validate_Abstract */
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class My_Validate_DateCompare extends Zend_Validate_Abstract
{
/**
* Error codes
* @const string
*/
const NOT_SAME = 'notSame';
const MISSING_TOKEN = 'missingToken';
const NOT_LATER = 'notLater';
const NOT_EARLIER = 'notEarlier';
const NOT_BETWEEN = 'notBetween';
/**
* Error messages
* @var array
*/
protected $_messageTemplates = array(
self::NOT_SAME => "The date '%value%' does not match the required",
self::NOT_BETWEEN => "The date is not in the valid range",
self::NOT_LATER => "The date '%value%' is not later than the required",
self::NOT_EARLIER => "The date '%value%' is not earlier than required",
self::MISSING_TOKEN => 'No date was provided to match against',
);
/**
* @var array
*/
protected $_messageVariables = array(
'token' => '_tokenString'
);
/**
* Original token against which to validate
* @var string
*/
protected $_tokenString;
protected $_token;
protected $_compare;
/**
* Sets validator options
*
* @param mixed $token
* @param mixed $compare
* @return void
*/
public function __construct($token = null, $compare = null)
{
if (null !== $token) {
$this->setToken($token);
$this->setCompare($compare);
}
}
/**
* Set token against which to compare
*
* @param mixed $token
* @return Zend_Validate_Identical
*/
public function setToken($token)
{
$this->_tokenString = (string) $token;
$this->_token = $token;
return $this;
}
/**
* Retrieve token
*
* @return string
*/
public function getToken()
{
return $this->_token;
}
/**
* Set compare against which to compare
*
* @param mixed $compare
* @return Zend_Validate_Identical
*/
public function setCompare($compare)
{
$this->_compareString = (string) $compare;
$this->_compare = $compare;
return $this;
}
/**
* Retrieve compare
*
* @return string
*/
public function getCompare()
{
return $this->_compare;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if a token has been set and the provided value
* matches that token.
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue((string) $value);
$token = $this->getToken();
if ($token === null) {
$this->_error(self::MISSING_TOKEN);
return false;
}
$date1 = new Zend_Date($value);
$date2 = new Zend_Date($token);
// Not Later
if ($this->getCompare() === true){
if ($date1->compare($date2) < 0 || $date1->equals($date2)) {
$this->_error(self::NOT_LATER);
return false;
}
// Not Earlier
} elseif ($this->getCompare() === false) {
if ($date1->compare($date2) > 0 || $date1->equals($date2)) {
$this->_error(self::NOT_EARLIER);
return false;
}
// Exact Match
} elseif ($this->getCompare() === null) {
if (!$date1->equals($date2)) {
$this->_error(self::NOT_SAME);
return false;
}
// In Range
} else {
$date3 = new Zend_Date($this->getCompare());
if ($date1->compare($date2) < 0 || $date1->compare($date3) > 0) {
$this->_error(self::NOT_BETWEEN);
return false;
}
}
// Date is valid
return true;
}
}
Usage:
$element->addValidator(new My_Validate_DateCompare('startdate')); //exact match
$element->addValidator(new My_Validate_DateCompare('startdate', null)); //exact match
$element->addValidator(new My_Validate_DateCompare('startdate', 'enddate')); //between dates
$element->addValidator(new My_Validate_DateCompare('startdate', true)); //not later
$element->addValidator(new My_Validate_DateCompare('startdate', false)); //not earlier
Uses the globally set date format (stored in Zend_Registry('Locale')).
It is also advisable to customize the error messages per case.
Latest update: fixed wrong default optional parameter which should be NULL instead of True. Changed the messages to be less confusing. Some formatting and whitespace.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With