From 166ed537d35a5ec36be6899a48fe5d8a977c6886 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Sun, 17 Jun 2012 15:56:12 -0400 Subject: [PATCH 01/30] [Form] Email element type hinting, cleanup --- test/ExplodeTest.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/ExplodeTest.php b/test/ExplodeTest.php index 73e9b957c..df11b2e3c 100644 --- a/test/ExplodeTest.php +++ b/test/ExplodeTest.php @@ -52,25 +52,25 @@ public function testRaisesExceptionWhenValidatorIsMissing() public function getExpectedData() { return array( - // value delim break N valid messages assertion - array('foo,bar,dev,null', ',', false, 4, true, array(), 'assertTrue'), - array('foo,bar,dev,null', ',', true, 1, false, array('X'), 'assertFalse'), - array('foo,bar,dev,null', ',', false, 4, false, array('X', 'X', 'X', 'X'), 'assertFalse'), - array('foo,bar,dev,null', ';', false, 1, true, array(), 'assertTrue'), - array('foo;bar,dev;null', ',', false, 2, true, array(), 'assertTrue'), - array('foo;bar,dev;null', ',', false, 2, false, array('X', 'X'), 'assertFalse'), - array('foo;bar;dev;null', ';', false, 4, true, array(), 'assertTrue'), - array('foo', ',', false, 1, true, array(), 'assertTrue'), - array('foo', ',', false, 1, false, array('X'), 'assertFalse'), - array('foo', ',', true, 1, false, array('X'), 'assertFalse'), - array(array(), ',', false, 0, true, array(Validator\Explode::INVALID => 'Invalid'), 'assertFalse'), + // value delim break N valid messages expects + array('foo,bar,dev,null', ',', false, 4, true, array(), true), + array('foo,bar,dev,null', ',', true, 1, false, array('X'), false), + array('foo,bar,dev,null', ',', false, 4, false, array('X', 'X', 'X', 'X'), false), + array('foo,bar,dev,null', ';', false, 1, true, array(), true), + array('foo;bar,dev;null', ',', false, 2, true, array(), true), + array('foo;bar,dev;null', ',', false, 2, false, array('X', 'X'), false), + array('foo;bar;dev;null', ';', false, 4, true, array(), true), + array('foo', ',', false, 1, true, array(), true), + array('foo', ',', false, 1, false, array('X'), false), + array('foo', ',', true, 1, false, array('X'), false), + array(array(), ',', false, 0, true, array(Validator\Explode::INVALID => 'Invalid'), false), ); } /** * @dataProvider getExpectedData */ - public function testExpectedBehavior($value, $delimiter, $breakOnFirst, $numIsValidCalls, $isValidReturn, $messages, $assertion) + public function testExpectedBehavior($value, $delimiter, $breakOnFirst, $numIsValidCalls, $isValidReturn, $messages, $expects) { $mockValidator = $this->getMock('Zend\Validator\ValidatorInterface'); $mockValidator->expects($this->exactly($numIsValidCalls))->method('isValid')->will($this->returnValue($isValidReturn)); @@ -83,7 +83,7 @@ public function testExpectedBehavior($value, $delimiter, $breakOnFirst, $numIsVa )); $validator->setMessage('Invalid', Validator\Explode::INVALID); - $this->$assertion($validator->isValid($value)); + $this->assertEquals($expects, $validator->isValid($value)); $this->assertEquals($messages, $validator->getMessages()); } From 92e23f70f2f75374ce74c847b719b1cb962229e8 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Wed, 20 Jun 2012 22:22:04 -0400 Subject: [PATCH 02/30] [Form] Url element - cleanup and test coverage updates --- src/Uri.php | 16 ++++++---------- test/UriTest.php | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/Uri.php b/src/Uri.php index 67c23babd..22ee1460d 100644 --- a/src/Uri.php +++ b/src/Uri.php @@ -20,9 +20,9 @@ namespace Zend\Validator; -use Traversable, - Zend\Uri\Uri as UriHandler, - Zend\Stdlib\ArrayUtils; +use Traversable; +use Zend\Uri\Uri as UriHandler; +use Zend\Stdlib\ArrayUtils; /** * @category Zend @@ -58,7 +58,6 @@ class Uri extends AbstractValidator */ protected $allowAbsolute = true; - /** * Sets default option values for this instance * @@ -177,12 +176,9 @@ public function isValid($value) try { $uriHandler->parse($value); if ($uriHandler->isValid()) { - if ($this->allowRelative && $this->allowAbsolute) { - return true; - } - - // settings must match result - if (($this->allowAbsolute && $uriHandler->isAbsolute()) + // It will either be a valid absolute or relative URI + if (($this->allowRelative && $this->allowAbsolute) + || ($this->allowAbsolute && $uriHandler->isAbsolute()) || ($this->allowRelative && $uriHandler->isValidRelative()) ) { return true; diff --git a/test/UriTest.php b/test/UriTest.php index dd13d923c..1cc85df20 100644 --- a/test/UriTest.php +++ b/test/UriTest.php @@ -21,8 +21,8 @@ namespace ZendTest\Validator; -use Zend\Validator, - ReflectionClass; +use Zend\Validator; +use ReflectionClass; /** * Test helper @@ -68,21 +68,22 @@ public function uriDataProvider() // Uri relative? absolute? array('http', true, false), array('http:', false, false), + //array('http:/', false, false), // TODO: FAILS array('http://', false, false), array('http:///', false, true), array('http://www.example.org/', false, true), array('http://www.example.org:80/', false, true), array('https://www.example.org/', false, true), array('https://www.example.org:80/', false, true), + array('example.org', true, false), + //array('example.org:', false, true), // TODO: FAILS array('http://foo', false, true), array('http://foo.local', false, true), - array('example.org', true, false), - array('example.org:', false, false), array('ftp://user:pass@example.org/', false, true), array('http://example.org/?cat=5&test=joo', false, true), array('http://www.fi/?cat=5&test=joo', false, true), - array('http://[::1]/', false, true), - array('http://[2620:0:1cfe:face:b00c::3]/', false, true), + //array('http://[::1]/', false, true), // TODO: FAILS + //array('http://[2620:0:1cfe:face:b00c::3]/', false, true), // TODO: FAILS array('http://[2620:0:1cfe:face:b00c::3]:80/', false, true), array('a:b', false, true), array('http://www.zend.com', false, true), @@ -99,7 +100,7 @@ public function uriDataProvider() /** * @dataProvider uriDataProvider */ - public function testDefaultSettingsValidation($uri, $isRelative, $isAbsolute) + public function testValidateAbsoluteOrRelativeAllowed($uri, $isRelative, $isAbsolute) { $validator = $this->validator; $this->assertTrue($validator->getAllowAbsolute()); @@ -113,7 +114,7 @@ public function testDefaultSettingsValidation($uri, $isRelative, $isAbsolute) /** * @dataProvider uriDataProvider */ - public function testIsAbsoluteOnlyValidation($uri, $isRelative, $isAbsolute) + public function testValidateAbsoluteOnly($uri, $isRelative, $isAbsolute) { $validator = $this->validator; $validator->setAllowAbsolute(true)->setAllowRelative(false); @@ -128,7 +129,7 @@ public function testIsAbsoluteOnlyValidation($uri, $isRelative, $isAbsolute) /** * @dataProvider uriDataProvider */ - public function testIsRelativeOnlyValidation($uri, $isRelative, $isAbsolute) + public function testValidateRelativeOnly($uri, $isRelative, $isAbsolute) { $validator = $this->validator; $validator->setAllowAbsolute(false)->setAllowRelative(true); From cee53e18f02f03c3cd2f7a28904d71525ecb1753 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Thu, 21 Jun 2012 23:31:21 -0400 Subject: [PATCH 03/30] [Form] Url element and validator better unit tests --- test/UriTest.php | 125 +++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 69 deletions(-) diff --git a/test/UriTest.php b/test/UriTest.php index 1cc85df20..3385a4dde 100644 --- a/test/UriTest.php +++ b/test/UriTest.php @@ -57,88 +57,75 @@ public function setUp() $this->validator = new Validator\Uri(); } - /** - * Data Provider for URIs, not necessarily complete - * - * @return array - */ - public function uriDataProvider() - { - return array( - // Uri relative? absolute? - array('http', true, false), - array('http:', false, false), - //array('http:/', false, false), // TODO: FAILS - array('http://', false, false), - array('http:///', false, true), - array('http://www.example.org/', false, true), - array('http://www.example.org:80/', false, true), - array('https://www.example.org/', false, true), - array('https://www.example.org:80/', false, true), - array('example.org', true, false), - //array('example.org:', false, true), // TODO: FAILS - array('http://foo', false, true), - array('http://foo.local', false, true), - array('ftp://user:pass@example.org/', false, true), - array('http://example.org/?cat=5&test=joo', false, true), - array('http://www.fi/?cat=5&test=joo', false, true), - //array('http://[::1]/', false, true), // TODO: FAILS - //array('http://[2620:0:1cfe:face:b00c::3]/', false, true), // TODO: FAILS - array('http://[2620:0:1cfe:face:b00c::3]:80/', false, true), - array('a:b', false, true), - array('http://www.zend.com', false, true), - array('https://example.com:10082/foo/bar?query', false, true), - array('../relative/path', true, false), - array('?queryOnly', true, false), - array('#fragmentOnly', true, false), - array('mailto:bob@example.com', false, true), - array('bob@example.com', true, false), - array('http://a_.!~*\'(-)n0123Di%25%26:pass;:&=+$,word@www.zend.com', false, true) - ); - } - - /** - * @dataProvider uriDataProvider - */ - public function testValidateAbsoluteOrRelativeAllowed($uri, $isRelative, $isAbsolute) + public function testHasDefaultSettingsAndLazyLoadsUriHandler() { $validator = $this->validator; - $this->assertTrue($validator->getAllowAbsolute()); - $this->assertTrue($validator->getAllowRelative()); - $uriHandler = $validator->getUriHandler(); $this->assertInstanceOf('Zend\Uri\Uri', $uriHandler); - $this->assertEquals(($isRelative || $isAbsolute), $validator->isValid($uri)); + $this->assertTrue($validator->getAllowRelative()); + $this->assertTrue($validator->getAllowAbsolute()); } - /** - * @dataProvider uriDataProvider - */ - public function testValidateAbsoluteOnly($uri, $isRelative, $isAbsolute) + public function testConstructorWithArraySetsOptions() { - $validator = $this->validator; - $validator->setAllowAbsolute(true)->setAllowRelative(false); - $this->assertTrue($validator->getAllowAbsolute()); + $uriMock = $this->getMock('Zend\Uri\Uri'); + $validator = new Validator\Uri(array( + 'uriHandler' => $uriMock, + 'allowRelative' => false, + 'allowAbsolute' => false, + )); + $this->assertEquals($uriMock, $validator->getUriHandler()); $this->assertFalse($validator->getAllowRelative()); - - $uriHandler = $validator->getUriHandler(); - $this->assertInstanceOf('Zend\Uri\Uri', $uriHandler); - $this->assertEquals($isAbsolute, $validator->isValid($uri)); + $this->assertFalse($validator->getAllowAbsolute()); } - /** - * @dataProvider uriDataProvider - */ - public function testValidateRelativeOnly($uri, $isRelative, $isAbsolute) + public function testConstructorWithArgsSetsOptions() { - $validator = $this->validator; - $validator->setAllowAbsolute(false)->setAllowRelative(true); + $uriMock = $this->getMock('Zend\Uri\Uri'); + $validator = new Validator\Uri($uriMock, false, false); + $this->assertEquals($uriMock, $validator->getUriHandler()); + $this->assertFalse($validator->getAllowRelative()); $this->assertFalse($validator->getAllowAbsolute()); - $this->assertTrue($validator->getAllowRelative()); + } - $uriHandler = $validator->getUriHandler(); - $this->assertInstanceOf('Zend\Uri\Uri', $uriHandler); - $this->assertEquals($isRelative, $validator->isValid($uri)); + public function allowOptionsDataProvider() + { + return array( + // allowAbsolute allowRelative isAbsolute isRelative isValid expects + array(true, true, true, false, true, true), + array(true, true, false, true, true, true), + array(false, true, true, false, true, false), + array(false, true, false, true, true, true), + array(true, false, true, false, true, true), + array(true, false, false, true, true, false), + array(false, false, true, false, true, false), + array(false, false, false, true, true, false), + array(true, true, false, false, false, false), + ); + } + + /** + * @dataProvider allowOptionsDataProvider + */ + public function testUriHandlerBehaviorWithAllowSettings( + $allowAbsolute, $allowRelative, $isAbsolute, $isRelative, $isValid, $expects + ) { + $uriMock = $this->getMock( + 'Zend\Uri\Uri', + array('parse', 'isValid', 'isAbsolute', 'isValidRelative') + ); + $uriMock->expects($this->once()) + ->method('isValid')->will($this->returnValue($isValid)); + $uriMock->expects($this->any()) + ->method('isAbsolute')->will($this->returnValue($isAbsolute)); + $uriMock->expects($this->any()) + ->method('isValidRelative')->will($this->returnValue($isRelative)); + + $this->validator->setUriHandler($uriMock) + ->setAllowAbsolute($allowAbsolute) + ->setAllowRelative($allowRelative); + + $this->assertEquals($expects, $this->validator->isValid('uri')); } /** From e197ced4c81d1b45d38a7673d401b90d014ec3f7 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Fri, 22 Jun 2012 00:24:53 -0400 Subject: [PATCH 04/30] [Form] Uri validator additional test coverage --- test/UriTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/UriTest.php b/test/UriTest.php index 3385a4dde..9d163cf52 100644 --- a/test/UriTest.php +++ b/test/UriTest.php @@ -23,6 +23,7 @@ use Zend\Validator; use ReflectionClass; +use Zend\Uri\Exception\InvalidArgumentException; /** * Test helper @@ -128,6 +129,17 @@ public function testUriHandlerBehaviorWithAllowSettings( $this->assertEquals($expects, $this->validator->isValid('uri')); } + public function testUriHandlerThrowsExceptionInParseMethodNotValid() + { + $uriMock = $this->getMock('Zend\Uri\Uri'); + $uriMock->expects($this->once()) + ->method('parse') + ->will($this->throwException(new InvalidArgumentException())); + + $this->validator->setUriHandler($uriMock); + $this->assertFalse($this->validator->isValid('uri')); + } + /** * Ensures that getMessages() returns expected default value * From 72d8a5ac4a6eaf8fb29bdc6f13499b20556a6238 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 21 Jun 2012 23:44:20 -0500 Subject: [PATCH 05/30] Better capabilities surrounding sharing - Added flag "sharedByDefault" to ServiceManager implementation, set to true by default - Disabling the flag disables storing created instances for re-use - Used with a variety of components: Cache, Crypt, Paginator, and the static variants of Filter and Validator - Cannot re-set the flag if allowOverride is false --- src/StaticValidator.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/StaticValidator.php b/src/StaticValidator.php index a16022de9..52e57577d 100644 --- a/src/StaticValidator.php +++ b/src/StaticValidator.php @@ -41,6 +41,10 @@ class StaticValidator */ public static function setPluginManager(ValidatorPluginManager $plugins = null) { + // Don't share by default to allow different arguments on subsequent calls + if ($plugins instanceof ValidatorPluginManager) { + $plugins->setShareByDefault(false); + } self::$plugins = $plugins; } @@ -69,11 +73,6 @@ public static function execute($value, $classBaseName, array $args = array()) $plugins = static::getPluginManager(); $validator = $plugins->get($classBaseName, $args); - $result = $validator->isValid($value); - - // Unregister validator in case different args are used on later invocation - $plugins->setService($classBaseName, null); - - return $result; + return $validator->isValid($value); } } From 4a63d7fca7606952d14efb2bf6607429c4a9ba6a Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 22 Jun 2012 00:36:09 -0500 Subject: [PATCH 06/30] Cleanup - Ensured all file and class level docblocks are correct - Removed all extraneous import statements - Ensured @throws and property annotations are correct --- src/ValidatorPluginManager.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/ValidatorPluginManager.php b/src/ValidatorPluginManager.php index 7314f94b2..c29e4214f 100644 --- a/src/ValidatorPluginManager.php +++ b/src/ValidatorPluginManager.php @@ -21,7 +21,6 @@ namespace Zend\Validator; use Zend\ServiceManager\AbstractPluginManager; -use Zend\ServiceManager\ConfigurationInterface; /** * @category Zend @@ -32,14 +31,7 @@ class ValidatorPluginManager extends AbstractPluginManager { /** - * Aliases for registered filter invokables - * - * @var array - */ - protected $aliases = array(); - - /** - * Default set of filters + * Default set of validators * * @var array */ From c9257188db3d5495290173b2b26a22a6681ed43c Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Sat, 23 Jun 2012 02:21:38 -0400 Subject: [PATCH 07/30] [Form] Date/Time elements and view helpers --- src/DateStep.php | 300 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 src/DateStep.php diff --git a/src/DateStep.php b/src/DateStep.php new file mode 100644 index 000000000..4942688f5 --- /dev/null +++ b/src/DateStep.php @@ -0,0 +1,300 @@ + "Invalid type given. String, integer, array or Zend_Date expected", + self::INVALID_DATE => "'%value%' does not appear to be a valid date", + self::NOT_STEP => "'%value%' is not a valid step." + ); + + /** + * Optional base date value + * + * @var string|integer|array|\Zend\Date\Date + */ + protected $baseValue = 0; + + /** + * Optional date step value (defaults to 1) + * + * @var string|integer|array|\Zend\Date\Date + */ + protected $stepValue = 1; + + /** + * Optional date step value (defaults to \Zend\Date\Date::DAY) + * + * @var string + */ + protected $stepDatePart = ZendDate\Date::DAY; + + /** + * Optional format to be used when the baseValue + * and validation value are strings to be converted + * to \Zend\Date\Date objects. + * + * @var string|null + */ + protected $format; + + /** + * Optional locale to be used when the baseValue + * and validation value are strings to be converted + * to \Zend\Date\Date objects. + * + * @var string|\Zend\Locale\Locale|null + */ + protected $locale; + + /** + * Set default options for this instance + * + * @param array $options + */ + public function __construct($options = array()) + { + if ($options instanceof Traversable) { + $options = ArrayUtils::iteratorToArray($options); + } elseif (!is_array($options)) { + $options = func_get_args(); + $temp['baseValue'] = array_shift($options); + if (!empty($options)) { + $temp['step'] = array_shift($options); + } + + $options = $temp; + } + + if (isset($options['baseValue'])) { + $this->setBaseValue($options['baseValue']); + } + if (isset($options['stepValue'])) { + $this->setStepValue($options['stepValue']); + } + if (isset($options['stepDatePart'])) { + $this->setStepDatePart($options['stepDatePart']); + } + if (array_key_exists('format', $options)) { + $this->setFormat($options['format']); + } + if (!isset($options['locale'])) { + if (Registry::isRegistered('Zend_Locale')) { + $options['locale'] = Registry::get('Zend_Locale'); + } + } + if (isset($options['locale'])) { + $this->setLocale($options['locale']); + } + + parent::__construct($options); + } + + /** + * Sets the base value from which the step should be computed + * + * @param string|integer|array|\Zend\Date\Date $baseValue + * @return DateStep + */ + public function setBaseValue($baseValue) + { + $this->baseValue = $baseValue; + return $this; + } + + /** + * Returns the base value from which the step should be computed + * + * @return string|integer|array|\Zend\Date\Date + */ + public function getBaseValue() + { + return $this->baseValue; + } + + /** + * Sets the step value + * + * @param string|integer|array|\Zend\Date\Date $step + * @return DateStep + */ + public function setStepValue($stepValue) + { + $this->stepValue = $stepValue; + return $this; + } + + /** + * Returns the step value + * + * @return string|integer|array|\Zend\Date\Date + */ + public function getStepValue() + { + return $this->stepValue; + } + + /** + * Sets the step date part + * + * @param string $stepDatePart + * @return DateStep + */ + public function setStepDatePart($stepDatePart) + { + $this->stepDatePart = $stepDatePart; + return $this; + } + + /** + * Returns the step date part + * + * @return string + */ + public function getStepDatePart() + { + return $this->stepValue; + } + + /** + * Returns the format option + * + * @return string|null + */ + public function getFormat() + { + return $this->format; + } + + /** + * Sets the format option + * + * @param string $format + * @return DateStep + */ + public function setFormat($format = null) + { + $this->format = $format; + return $this; + } + + /** + * Returns the locale option + * + * @return string|Locale|null + */ + public function getLocale() + { + return $this->locale; + } + + /** + * Sets the locale option + * + * @param string|Locale $locale + * @return DateStep + */ + public function setLocale($locale = null) + { + $this->locale = Locale::findLocale($locale); + return $this; + } + + /** + * Returns true if $value is a scalar and a valid step value + * + * @param mixed $value + * @return bool + * @throws Exception\InvalidArgumentException|\Zend\Date\Exception + */ + public function isValid($value) + { + if (!is_string($value) + && !is_int($value) + && !is_float($value) + && !is_array($value) + && !($value instanceof ZendDate\Date) + ) { + $this->error(self::INVALID); + return false; + } + + $this->setValue($value); + + $format = $this->getFormat(); + $locale = $this->getLocale(); + $baseValue = $this->getBaseValue(); + $stepValue = $this->getStepValue(); + $stepDatePart = $this->getStepDatePart(); + + // Confirm that baseValue and value are dates + if (!ZendDate\Date::isDate($baseValue, $format, $locale)) { + throw new Exception\InvalidArgumentException('Invalid baseValue given'); + } + + if (!ZendDate\Date::isDate($value, $format, $locale)) { + $this->error(self::INVALID_DATE); + return false; + } + + // Convert baseValue and value to Date objects + $baseDate = new ZendDate\Date($baseValue, $format, $locale); + $valueDate = new ZendDate\Date($value, $format, $locale); + + if ($valueDate->equals($baseDate)) { + return true; + } + + // Keep adding steps to the base date until a match is found + // or until the value is exceeded + while ($baseDate->isEarlier($valueDate)) { + $baseDate->add($stepValue, $stepDatePart, $locale); + if ($baseDate->equals($valueDate)) { + return true; + } + } + + return false; + } +} From a5af2efd12798327563c241cdbb5e8178a87466d Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Sun, 24 Jun 2012 22:04:45 -0400 Subject: [PATCH 08/30] [Form] Date/Time elements, view helpers, DateStep validator and tests --- src/DateStep.php | 332 ++++++++++++++++++++++++++++-------------- test/DateStepTest.php | 162 +++++++++++++++++++++ 2 files changed, 387 insertions(+), 107 deletions(-) create mode 100644 test/DateStepTest.php diff --git a/src/DateStep.php b/src/DateStep.php index 4942688f5..438b628f4 100644 --- a/src/DateStep.php +++ b/src/DateStep.php @@ -21,10 +21,10 @@ namespace Zend\Validator; use Traversable; -use Zend\Date as ZendDate; -use Zend\Locale\Format; -use Zend\Locale\Locale; -use Zend\Registry; +use DateTime; +use DateTimeZone; +use DateInterval; +use DatePeriod; use Zend\Stdlib\ArrayUtils; use Zend\Validator\Exception; @@ -52,41 +52,32 @@ class DateStep extends AbstractValidator /** * Optional base date value * - * @var string|integer|array|\Zend\Date\Date + * @var string|integer|\DateTime */ - protected $baseValue = 0; + protected $baseValue = '1970-01-01T00:00:00Z'; /** - * Optional date step value (defaults to 1) + * Date step interval (defaults to 1 day). + * Uses the DateInterval specification. * - * @var string|integer|array|\Zend\Date\Date + * @var DateInterval */ - protected $stepValue = 1; + protected $stepInterval; /** - * Optional date step value (defaults to \Zend\Date\Date::DAY) + * Format to use for parsing date strings * * @var string */ - protected $stepDatePart = ZendDate\Date::DAY; + protected $format = DateTime::ISO8601; /** - * Optional format to be used when the baseValue - * and validation value are strings to be converted - * to \Zend\Date\Date objects. + * Optional timezone to be used when the baseValue + * and validation values do not contain timezone info * - * @var string|null + * @var DateTimeZone */ - protected $format; - - /** - * Optional locale to be used when the baseValue - * and validation value are strings to be converted - * to \Zend\Date\Date objects. - * - * @var string|\Zend\Locale\Locale|null - */ - protected $locale; + protected $timezone; /** * Set default options for this instance @@ -101,7 +92,13 @@ public function __construct($options = array()) $options = func_get_args(); $temp['baseValue'] = array_shift($options); if (!empty($options)) { - $temp['step'] = array_shift($options); + $temp['stepInterval'] = array_shift($options); + } + if (!empty($options)) { + $temp['format'] = array_shift($options); + } + if (!empty($options)) { + $temp['timezone'] = array_shift($options); } $options = $temp; @@ -110,22 +107,18 @@ public function __construct($options = array()) if (isset($options['baseValue'])) { $this->setBaseValue($options['baseValue']); } - if (isset($options['stepValue'])) { - $this->setStepValue($options['stepValue']); - } - if (isset($options['stepDatePart'])) { - $this->setStepDatePart($options['stepDatePart']); + if (isset($options['stepInterval'])) { + $this->setStepInterval($options['stepInterval']); + } else { + $this->setStepInterval(new DateInterval('P1D')); } if (array_key_exists('format', $options)) { $this->setFormat($options['format']); } - if (!isset($options['locale'])) { - if (Registry::isRegistered('Zend_Locale')) { - $options['locale'] = Registry::get('Zend_Locale'); - } - } - if (isset($options['locale'])) { - $this->setLocale($options['locale']); + if (isset($options['timezone'])) { + $this->setTimezone($options['timezone']); + } else { + $this->setTimezone(new DateTimeZone(date_default_timezone_get())); } parent::__construct($options); @@ -134,7 +127,7 @@ public function __construct($options = array()) /** * Sets the base value from which the step should be computed * - * @param string|integer|array|\Zend\Date\Date $baseValue + * @param string|integer|\DateTime $baseValue * @return DateStep */ public function setBaseValue($baseValue) @@ -146,7 +139,7 @@ public function setBaseValue($baseValue) /** * Returns the base value from which the step should be computed * - * @return string|integer|array|\Zend\Date\Date + * @return string|integer|\DateTime */ public function getBaseValue() { @@ -154,53 +147,31 @@ public function getBaseValue() } /** - * Sets the step value - * - * @param string|integer|array|\Zend\Date\Date $step - * @return DateStep - */ - public function setStepValue($stepValue) - { - $this->stepValue = $stepValue; - return $this; - } - - /** - * Returns the step value - * - * @return string|integer|array|\Zend\Date\Date - */ - public function getStepValue() - { - return $this->stepValue; - } - - /** - * Sets the step date part + * Sets the step date interval * - * @param string $stepDatePart + * @param DateInterval $stepValue * @return DateStep */ - public function setStepDatePart($stepDatePart) + public function setStepInterval(DateInterval $stepInterval) { - $this->stepDatePart = $stepDatePart; + $this->stepInterval = $stepInterval; return $this; } /** - * Returns the step date part + * Returns the step date interval * - * @return string + * @return DateInterval */ - public function getStepDatePart() + public function getStepInterval() { - return $this->stepValue; + return $this->stepInterval; } /** * Returns the format option * - * @return string|null + * @return string */ public function getFormat() { @@ -213,48 +184,79 @@ public function getFormat() * @param string $format * @return DateStep */ - public function setFormat($format = null) + public function setFormat($format) { $this->format = $format; return $this; } /** - * Returns the locale option + * Returns the timezone option * - * @return string|Locale|null + * @return DateTimeZone */ - public function getLocale() + public function getTimezone() { - return $this->locale; + return $this->timezone; } /** - * Sets the locale option + * Sets the timezone option * - * @param string|Locale $locale + * @param DateTimeZone $timezone * @return DateStep */ - public function setLocale($locale = null) + public function setTimezone(DateTimeZone $timezone) { - $this->locale = Locale::findLocale($locale); + $this->timezone = $timezone; return $this; } /** - * Returns true if $value is a scalar and a valid step value + * Converts an int or string to a DateTime object + * + * @param string|integer|\DateTime $param + * @return \DateTime + * @throws Exception\InvalidArgumentException + */ + protected function convertToDateTime($param) + { + $dateObj = $param; + if (is_int($param)) { + // Convert from timestamp + $dateObj = date_create("@$param"); + } else if (is_string($param)) { + // Custom week format support + if (strpos($this->getFormat(), 'Y-\WW') === 0 + && preg_match('/^([0-9]{4})\-W([0-9]{2})/', $param, $matches) + ) { + $dateObj = new DateTime(); + $dateObj->setISODate($matches[1], $matches[2]); + } else { + $dateObj = DateTime::createFromFormat( + $this->getFormat(), $param, $this->getTimezone() + ); + } + } + if (!($dateObj instanceof DateTime)) { + throw new Exception\InvalidArgumentException('Invalid date param given'); + } + + return $dateObj; + } + + /** + * Returns true if a date is within a valid step * - * @param mixed $value + * @param string|integer|\DateTime $value * @return bool - * @throws Exception\InvalidArgumentException|\Zend\Date\Exception + * @throws Exception\InvalidArgumentException */ public function isValid($value) { if (!is_string($value) && !is_int($value) - && !is_float($value) - && !is_array($value) - && !($value instanceof ZendDate\Date) + && !($value instanceof DateTime) ) { $this->error(self::INVALID); return false; @@ -262,39 +264,155 @@ public function isValid($value) $this->setValue($value); - $format = $this->getFormat(); - $locale = $this->getLocale(); - $baseValue = $this->getBaseValue(); - $stepValue = $this->getStepValue(); - $stepDatePart = $this->getStepDatePart(); - - // Confirm that baseValue and value are dates - if (!ZendDate\Date::isDate($baseValue, $format, $locale)) { - throw new Exception\InvalidArgumentException('Invalid baseValue given'); - } + $baseDate = $this->convertToDateTime($this->getBaseValue()); + $stepInterval = $this->getStepInterval(); - if (!ZendDate\Date::isDate($value, $format, $locale)) { + // Parse the date + try { + $valueDate = $this->convertToDateTime($value); + } catch (Exception\InvalidArgumentException $ex) { $this->error(self::INVALID_DATE); return false; } - // Convert baseValue and value to Date objects - $baseDate = new ZendDate\Date($baseValue, $format, $locale); - $valueDate = new ZendDate\Date($value, $format, $locale); - - if ($valueDate->equals($baseDate)) { + // Same date? + if ($valueDate == $baseDate) { return true; } + // Optimization for simple intervals. + // Handle intervals of just one date or time unit. + $intervalParts = explode('|', $stepInterval->format('%y|%m|%d|%h|%i|%s')); + $partCounts = array_count_values($intervalParts); + if (5 === $partCounts["0"]) { + // Find the unit with the non-zero interval + $unitKeys = array('years', 'months', 'days', 'hours', 'minutes', 'seconds'); + $intervalParts = array_combine($unitKeys, $intervalParts); + + $intervalUnit = null; + $stepValue = null; + foreach ($intervalParts as $key => $value) { + if (0 != $value) { + $intervalUnit = $key; + $stepValue = (int)$value; + break; + } + } + + // Get absolute time difference + $timeDiff = $valueDate->diff($baseDate, true); + $diffParts = explode('|', $timeDiff->format('%y|%m|%d|%h|%i|%s')); + $diffParts = array_combine($unitKeys, $diffParts); + + // Check date units + if (in_array($intervalUnit, array('years', 'months', 'days'))) { + switch ($intervalUnit) { + case 'years': + if ( 0 == $diffParts['months'] && 0 == $diffParts['days'] + && 0 == $diffParts['hours'] && 0 == $diffParts['minutes'] + && 0 == $diffParts['seconds'] + ) { + if (($diffParts['years'] % $stepValue) === 0) { + return true; + } + } + break; + case 'months': + if ( 0 == $diffParts['days'] && 0 == $diffParts['hours'] + && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] + ) { + $months = ($diffParts['years'] * 12) + $diffParts['months']; + if (($months % $stepValue) === 0) { + return true; + } + } + break; + case 'days': + if ( 0 == $diffParts['hours'] && 0 == $diffParts['minutes'] + && 0 == $diffParts['seconds'] + ) { + $days = $timeDiff->format('%a'); // Total days + if (($days % $stepValue) === 0) { + return true; + } + } + break; + } + $this->error(self::NOT_STEP); + return false; + } + + // Check time units + if (in_array($intervalUnit, array('hours', 'minutes', 'seconds'))) { + + // Simple test if $stepValue is 1. + if (1 == $stepValue) { + if ('hours' === $intervalUnit + && 0 == $diffParts['minutes'] && 0 == $diffParts['seconds'] + ) { + return true; + } else if ('minutes' === $intervalUnit && 0 == $diffParts['seconds']) { + return true; + } else if ('seconds' === $intervalUnit) { + return true; + } + } + + // Simple test for same day, when using default baseDate + if ($baseDate->format('Y-m-d') == $valueDate->format('Y-m-d') + && $baseDate->format('Y-m-d') == '1970-01-01' + ) { + switch ($intervalUnit) { + case 'hours': + if (0 == $diffParts['minutes'] && 0 == $diffParts['seconds']) { + if (($diffParts['hours'] % $stepValue) === 0) { + return true; + } + } + break; + case 'minutes': + if (0 == $diffParts['seconds']) { + $minutes = ($diffParts['hours'] * 60) + $diffParts['minutes']; + if (($minutes % $stepValue) === 0) { + return true; + } + } + break; + case 'seconds': + $seconds = ($diffParts['hours'] * 60) + + ($diffParts['minutes'] * 60) + + $diffParts['seconds']; + if (($seconds % $stepValue) === 0) { + return true; + } + break; + } + $this->error(self::NOT_STEP); + return false; + } + } + } + + // Fall back to slower (but accurate) method for complex intervals. // Keep adding steps to the base date until a match is found - // or until the value is exceeded - while ($baseDate->isEarlier($valueDate)) { - $baseDate->add($stepValue, $stepDatePart, $locale); - if ($baseDate->equals($valueDate)) { - return true; + // or until the value is exceeded. + if ($baseDate < $valueDate) { + while ($baseDate < $valueDate) { + $baseDate->add($stepInterval); + if ($baseDate == $valueDate) { + return true; + } + } + } else { + while ($baseDate > $valueDate) { + $baseDate->sub($stepInterval); + if ($baseDate == $valueDate) { + return true; + } } } + $this->error(self::NOT_STEP); return false; } } diff --git a/test/DateStepTest.php b/test/DateStepTest.php new file mode 100644 index 000000000..120873e07 --- /dev/null +++ b/test/DateStepTest.php @@ -0,0 +1,162 @@ + $format, + 'baseValue' => $baseValue, + 'stepInterval' => new DateInterval($interval), + )); + + $this->assertEquals($isValid, $validator->isValid($value)); + } + + public function testGetMessagesReturnsDefaultValue() + { + $validator = new Validator\DateStep(); + $this->assertEquals(array(), $validator->getMessages()); + } + + public function testEqualsMessageTemplates() + { + $validator = new Validator\DateStep(array()); + $reflection = new ReflectionClass($validator); + + if (!$reflection->hasProperty('_messageTemplates')) { + return; + } + + $property = $reflection->getProperty('_messageTemplates'); + $property->setAccessible(true); + + $this->assertEquals( + $property->getValue($validator), + $validator->getOption('messageTemplates') + ); + } + + public function testEqualsMessageVariables() + { + $validator = new Validator\DateStep(array()); + $reflection = new ReflectionClass($validator); + + if (!$reflection->hasProperty('_messageVariables')) { + return; + } + + $property = $reflection->getProperty('_messageVariables'); + $property->setAccessible(true); + + $this->assertEquals( + $property->getValue($validator), + $validator->getOption('messageVariables') + ); + } +} From cc0a40d2b57178874ca8dcc78577de97cee9dd5b Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Sun, 24 Jun 2012 22:09:02 -0400 Subject: [PATCH 09/30] [Form] DateStep Validator add to ValidatorLoader --- src/ValidatorLoader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ValidatorLoader.php b/src/ValidatorLoader.php index 55070c413..43b62a069 100644 --- a/src/ValidatorLoader.php +++ b/src/ValidatorLoader.php @@ -143,6 +143,7 @@ class ValidatorLoader extends PluginClassLoader 'creditcard' => 'Zend\Validator\CreditCard', 'csrf' => 'Zend\Validator\Csrf', 'date' => 'Zend\Validator\Date', + 'datestep' => 'Zend\Validator\DateStep', 'db_\\no_record_exists' => 'Zend\Validator\Db\NoRecordExists', 'db_\\norecordexists' => 'Zend\Validator\Db\NoRecordExists', 'db\\no_record_exists' => 'Zend\Validator\Db\NoRecordExists', From dd4e998f82b363a874dc899279cf5de1bf430bf3 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Mon, 25 Jun 2012 22:40:56 -0400 Subject: [PATCH 10/30] [i18n] Date Validator changed to use DateTime --- src/Date.php | 163 ++++++----------------------- test/DateTest.php | 254 +++++++++++----------------------------------- 2 files changed, 92 insertions(+), 325 deletions(-) diff --git a/src/Date.php b/src/Date.php index 4f20c4d55..e9901eda5 100644 --- a/src/Date.php +++ b/src/Date.php @@ -20,12 +20,9 @@ namespace Zend\Validator; -use Traversable, - Zend\Date as ZendDate, - Zend\Locale\Format, - Zend\Locale\Locale, - Zend\Registry, - Zend\Stdlib\ArrayUtils; +use Traversable; +use DateTime; +use Zend\Stdlib\ArrayUtils; /** * @category Zend @@ -45,7 +42,7 @@ class Date extends AbstractValidator * @var array */ protected $_messageTemplates = array( - self::INVALID => "Invalid type given. String, integer, array or Zend_Date expected", + self::INVALID => "Invalid type given. String, integer, array or DateTime expected", self::INVALID_DATE => "'%value%' does not appear to be a valid date", self::FALSEFORMAT => "'%value%' does not fit the date format '%format%'", ); @@ -64,13 +61,6 @@ class Date extends AbstractValidator */ protected $format; - /** - * Optional locale - * - * @var string|\Zend\Locale\Locale|null - */ - protected $locale; - /** * Sets validator options * @@ -84,10 +74,6 @@ public function __construct($options = array()) } elseif (!is_array($options)) { $options = func_get_args(); $temp['format'] = array_shift($options); - if (!empty($options)) { - $temp['locale'] = array_shift($options); - } - $options = $temp; } @@ -95,41 +81,9 @@ public function __construct($options = array()) $this->setFormat($options['format']); } - if (!array_key_exists('locale', $options)) { - if (Registry::isRegistered('Zend_Locale')) { - $options['locale'] = Registry::get('Zend_Locale'); - } - } - - if (array_key_exists('locale', $options)) { - $this->setLocale($options['locale']); - } - parent::__construct($options); } - /** - * Returns the locale option - * - * @return string|Locale|null - */ - public function getLocale() - { - return $this->locale; - } - - /** - * Sets the locale option - * - * @param string|Locale $locale - * @return Date provides a fluent interface - */ - public function setLocale($locale = null) - { - $this->locale = Locale::findLocale($locale); - return $this; - } - /** * Returns the locale option * @@ -154,19 +108,18 @@ public function setFormat($format = null) /** * Returns true if $value is a valid date of the format YYYY-MM-DD - * If optional $format or $locale is set the date format is checked - * according to Zend_Date, see Zend_Date::isDate() + * If optional $format is set the date format is checked + * according to DateTime * - * @param string|array|ZendDate $value + * @param string|array|int|DateTime $value * @return boolean */ public function isValid($value) { - if (!is_string($value) - && !is_int($value) - && !is_float($value) - && !is_array($value) - && !($value instanceof ZendDate\Date) + if (!is_string($value) + && !is_array($value) + && !is_int($value) + && !($value instanceof DateTime) ) { $this->error(self::INVALID); return false; @@ -174,22 +127,32 @@ public function isValid($value) $this->setValue($value); - if (($this->format !== null) - || ($this->locale !== null) - || is_array($value) - || $value instanceof ZendDate\Date + $format = $this->getFormat(); + + if ($value instanceof DateTime) { + return true; + } elseif (is_int($value) + || (is_string($value) && null !== $format) ) { - if (!ZendDate\Date::isDate($value, $this->format, $this->locale)) { - if ($this->checkFormat($value) === false) { - $this->error(self::FALSEFORMAT); - } else { - $this->error(self::INVALID_DATE); - } + $date = (is_int($value)) + ? date_create("@$value") // from timestamp + : DateTime::createFromFormat($format, $value); + + // Invalid dates can show up as warnings (ie. "2007-02-99") + // and still return a DateTime object + $errors = DateTime::getLastErrors(); + + if (false === $date || $errors['warning_count'] > 0) { + $this->error(self::INVALID_DATE); return false; } } else { + if (is_array($value)) { + $value = implode('-', $value); + } + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) { - $this->format = 'yyyy-MM-dd'; + $this->format = 'Y-m-d'; $this->error(self::FALSEFORMAT); $this->format = null; return false; @@ -206,66 +169,4 @@ public function isValid($value) return true; } - /** - * Check if the given date fits the given format - * - * @param string $value Date to check - * @return boolean False when date does not fit the format - */ - private function checkFormat($value) - { - try { - $parsed = Format::getDate((string) $value, array( - 'date_format' => $this->format, - 'format_type' => 'iso', - 'fix_date' => false, - )); - if (isset($parsed['year']) - && ((strpos(strtoupper($this->format), 'YY') !== false) - && (strpos(strtoupper($this->format), 'YYYY') === false)) - ) { - $parsed['year'] = ZendDate\Date::getFullYear($parsed['year']); - } - } catch (\Exception $e) { - // Date can not be parsed - return false; - } - - if (((strpos($this->format, 'Y') !== false) || (strpos($this->format, 'y') !== false)) - && (!isset($parsed['year'])) - ) { - // Year expected but not found - return false; - } - - if ((strpos($this->format, 'M') !== false) && (!isset($parsed['month']))) { - // Month expected but not found - return false; - } - - if ((strpos($this->format, 'd') !== false) && (!isset($parsed['day']))) { - // Day expected but not found - return false; - } - - if (((strpos($this->format, 'H') !== false) || (strpos($this->format, 'h') !== false)) - && (!isset($parsed['hour'])) - ) { - // Hour expected but not found - return false; - } - - if ((strpos($this->format, 'm') !== false) && (!isset($parsed['minute']))) { - // Minute expected but not found - return false; - } - - if ((strpos($this->format, 's') !== false) && (!isset($parsed['second']))) { - // Second expected but not found - return false; - } - - // Date fits the format - return true; - } } diff --git a/test/DateTest.php b/test/DateTest.php index 5d54d30c1..fa67726d5 100644 --- a/test/DateTest.php +++ b/test/DateTest.php @@ -21,10 +21,9 @@ namespace ZendTest\Validator; -use Zend\Validator, - Zend\Date, - Zend\Registry, - ReflectionClass; +use Zend\Validator; +use DateTime; +use ReflectionClass; /** * Test helper @@ -45,84 +44,76 @@ class DateTest extends \PHPUnit_Framework_TestCase { /** - * Zend_Validator_Date object + * Zend\Validator\Date object * - * @var Zend_Validator_Date + * @var Validator\Date */ protected $_validator; /** - * Whether an error occurred - * - * @var boolean - */ - protected $_errorOccurred = false; - - /** - * Creates a new Zend_Validator_Date object for each test method + * Creates a new Zend\Validator\Date object for each test method * * @return void */ public function setUp() { - Registry::_unsetInstance(); - $this->_errorOccurred = false; - $this->_validator = new Validator\Date(); + $this->_validator = new Validator\Date(); } - /** - * Ensures that the validator follows expected behavior - * - * @return void - */ - public function testBasic() + public function datesDataProvider() { - $valuesExpected = array( - '2007-01-01' => true, - '2007-02-28' => true, - '2007-02-29' => false, - '2008-02-29' => true, - '2007-02-30' => false, - '2007-02-99' => false, - '9999-99-99' => false, - 0 => false, - 999999999999 => false, - 'Jan 1 2007' => false, - 'asdasda' => false, - 'sdgsdg' => false - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals($result, $this->_validator->isValid($input), - "'$input' expected to be " . ($result ? '' : 'in') . 'valid'); - } - } - - /** - * Ensures that characters trailing an otherwise valid date cause the input to be invalid - * - * @group ZF-1804 - * @return void - */ - public function testCharactersTrailingInvalid() - { - $dateValid = '2007-08-02'; - $charactersTrailing = 'something'; - $this->assertTrue($this->_validator->isValid($dateValid)); - $this->assertFalse($this->_validator->isValid($dateValid . $charactersTrailing)); + return array( + // date format isValid + array('2007-01-01', null, true), + array('2007-02-28', null, true), + array('2007-02-29', null, false), + array('2008-02-29', null, true), + array('2007-02-30', null, false), + array('2007-02-99', null, false), + array('2007-02-99', 'Y-m-d', false), + array('9999-99-99', null, false), + array('9999-99-99', 'Y-m-d', false), + array('Jan 1 2007', null, false), + array('Jan 1 2007', 'M j Y', true), + array('asdasda', null, false), + array('sdgsdg', null, false), + array('2007-01-01something', null, false), + array('something2007-01-01', null, false), + array('10.01.2008', 'd.m.Y', true), + array('01 2010', 'm Y', true), + array('2008/10/22', 'd/m/Y', false), + array('22/10/08', 'd/m/y', true), + array('22/10', 'd/m/Y', false), + // time + array('2007-01-01T12:02:55Z', DateTime::ISO8601, true), + array('12:02:55', 'H:i:s', true), + array('25:02:55', 'H:i:s', false), + // int + array(0, null, true), + array(1340677235, null, true), + array(999999999999, null, false), + // array + array(array('2012', '06', '25'), null, true), + array(array('12', '06', '25'), null, false), + array(array(1 => 1), null, false), + // DateTime + array(new DateTime(), null, true), + // invalid obj + array(new \stdClass(), null, false), + ); } /** - * Ensures that characters leading an otherwise valid date cause the input to be invalid + * Ensures that the validator follows expected behavior * - * @group ZF-1804 + * @dataProvider datesDataProvider * @return void */ - public function testCharactersLeadingInvalid() + public function testBasic($input, $format, $result) { - $dateValid = '2007-08-02'; - $charactersLeading = 'something'; - $this->assertTrue($this->_validator->isValid($dateValid)); - $this->assertFalse($this->_validator->isValid($charactersLeading . $dateValid)); + $this->_validator->setFormat($format); + $this->assertEquals($result, $this->_validator->isValid($input)); + $this->assertEquals($format, $this->_validator->getFormat()); } /** @@ -135,140 +126,15 @@ public function testGetMessages() $this->assertEquals(array(), $this->_validator->getMessages()); } - /** - * Ensures that the validator can handle different manual dateformats - * - * @group ZF-2003 - * @return void - */ - public function testUseManualFormat() - { - $this->assertTrue($this->_validator->setFormat('dd.MM.YYYY')->isValid('10.01.2008')); - $this->assertEquals('dd.MM.YYYY', $this->_validator->getFormat()); - - $this->assertTrue($this->_validator->setFormat('MM yyyy')->isValid('01 2010')); - $this->assertFalse($this->_validator->setFormat('dd/MM/yyyy')->isValid('2008/10/22')); - $this->assertTrue($this->_validator->setFormat('dd/MM/yy')->isValid('22/10/08')); - $this->assertFalse($this->_validator->setFormat('dd/MM/yy')->isValid('22/10')); - $this->assertFalse($this->_validator->setFormat('s')->isValid(0)); - } - - /** - * Ensures that the validator can handle different dateformats from locale - * - * @group ZF-2003 - * @return void - */ - public function testUseLocaleFormat() - { - $errorOccurredLocal = false; - set_error_handler(array($this, 'errorHandlerIgnore')); - $valuesExpected = array( - '10.01.2008' => true, - '32.02.2008' => false, - '20 April 2008' => true, - '1 Jul 2008' => true, - '2008/20/03' => false, - '99/99/2000' => false, - 0 => false, - 999999999999 => false, - 'Jan 1 2007' => false - ); - foreach ($valuesExpected as $input => $resultExpected) { - $resultActual = $this->_validator->setLocale('de_AT')->isValid($input); - if (!$this->_errorOccurred) { - $this->assertEquals($resultExpected, $resultActual, "'$input' expected to be " - . ($resultExpected ? '' : 'in') . 'valid'); - } else { - $errorOccurredLocal = true; - } - $this->_errorOccurred = false; - } - $this->assertEquals('de_AT', $this->_validator->getLocale()); - restore_error_handler(); - if ($errorOccurredLocal) { - $this->markTestSkipped('Affected by bug described in ZF-2789'); - } - } - - /** - * Ensures that the validator can handle different dateformats from locale - * - * @group ZF-2003 - * @return void - */ - public function testLocaleContructor() - { - set_error_handler(array($this, 'errorHandlerIgnore')); - $valid = new Validator\Date('dd.MM.YYYY', 'de'); - $this->assertTrue($valid->isValid('10.April.2008')); - - restore_error_handler(); - } - - /** - * @ZF-4352 - */ - public function testNonStringValidation() - { - $this->assertFalse($this->_validator->isValid(array(1 => 1))); - } - - /** - * @ZF-6374 - */ - public function testUsingApplicationLocale() - { - \Zend\Registry::set('Zend_Locale', new \Zend\Locale\Locale('de')); - $valid = new Validator\Date(); - $this->assertTrue($valid->isValid('10.April.2008')); - } - - /** - * @group fml - * ZF-7630 - */ - public function testDateObjectVerification() - { - $date = new Date\Date(); - $this->assertTrue($this->_validator->isValid($date), "'$date' expected to be valid"); - } - - /** - * ZF-6457 - */ - public function testArrayVerification() - { - $date = new Date\Date(); - $array = $date->toArray(); - $this->assertTrue($this->_validator->isValid($array), "array expected to be valid"); - } - - /** - * Ignores a raised PHP error when in effect, but throws a flag to indicate an error occurred - * - * @param integer $errno - * @param string $errstr - * @param string $errfile - * @param integer $errline - * @param array $errcontext - * @return void - * @group ZF-2789 - */ - public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $errcontext) - { - $this->_errorOccurred = true; - } - public function testEqualsMessageTemplates() { $validator = $this->_validator; $reflection = new ReflectionClass($validator); - - if(!$reflection->hasProperty('_messageTemplates')) { + + if (!$reflection->hasProperty('_messageTemplates')) { return; } - + $property = $reflection->getProperty('_messageTemplates'); $property->setAccessible(true); @@ -277,16 +143,16 @@ public function testEqualsMessageTemplates() $validator->getOption('messageTemplates') ); } - + public function testEqualsMessageVariables() { $validator = $this->_validator; $reflection = new ReflectionClass($validator); - - if(!$reflection->hasProperty('_messageVariables')) { + + if (!$reflection->hasProperty('_messageVariables')) { return; } - + $property = $reflection->getProperty('_messageVariables'); $property->setAccessible(true); From 83146f0c799a2aa0bdd298f12ce9f4f2ef223e15 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Mon, 25 Jun 2012 22:51:21 -0400 Subject: [PATCH 11/30] [i18n] Date Validator comment fix --- src/Date.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Date.php b/src/Date.php index e9901eda5..cf8abfba7 100644 --- a/src/Date.php +++ b/src/Date.php @@ -85,7 +85,7 @@ public function __construct($options = array()) } /** - * Returns the locale option + * Returns the format option * * @return string|null */ From ec0a653e4f720063dc47f3f263655418f7ab08f6 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Sun, 24 Jun 2012 23:55:28 +0200 Subject: [PATCH 12/30] [Validator] Remove deprecated code --- src/ValidatorChain.php | 21 --------------------- test/ValidateTest.php | 3 --- 2 files changed, 24 deletions(-) diff --git a/src/ValidatorChain.php b/src/ValidatorChain.php index c3377b3f5..8f0c3eac3 100644 --- a/src/ValidatorChain.php +++ b/src/ValidatorChain.php @@ -51,14 +51,6 @@ class ValidatorChain implements */ protected $messages = array(); - /** - * Array of validation failure message codes - * - * @var array - * @deprecated Since 1.5.0 - */ - protected $errors = array(); - /** * Return the count of attached validators * @@ -189,7 +181,6 @@ public function prependByName($name, $options = array(), $breakChainOnFailure = public function isValid($value, $context = null) { $this->messages = array(); - $this->errors = array(); $result = true; foreach ($this->validators as $element) { $validator = $element['instance']; @@ -199,7 +190,6 @@ public function isValid($value, $context = null) $result = false; $messages = $validator->getMessages(); $this->messages = array_merge($this->messages, $messages); - $this->errors = array_merge($this->errors, array_keys($messages)); if ($element['breakChainOnFailure']) { break; } @@ -217,17 +207,6 @@ public function getMessages() return $this->messages; } - /** - * Returns array of validation failure message codes - * - * @return array - * @deprecated Since 1.5.0 - */ - public function getErrors() - { - return $this->errors; - } - /** * Invoke chain as command * diff --git a/test/ValidateTest.php b/test/ValidateTest.php index 4b96577fd..7db15f2bf 100644 --- a/test/ValidateTest.php +++ b/test/ValidateTest.php @@ -68,9 +68,7 @@ public function setUp() public function testEmpty() { $this->assertEquals(array(), $this->validator->getMessages()); - $this->assertEquals(array(), $this->validator->getErrors()); $this->assertTrue($this->validator->isValid('something')); - $this->assertEquals(array(), $this->validator->getErrors()); } /** @@ -83,7 +81,6 @@ public function testTrue() $this->validator->addValidator(new ValidatorTrue()); $this->assertTrue($this->validator->isValid(null)); $this->assertEquals(array(), $this->validator->getMessages()); - $this->assertEquals(array(), $this->validator->getErrors()); } /** From 9432cd342b6c544839123d67fd01a1169b3c9c11 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 25 Jun 2012 08:42:42 +0200 Subject: [PATCH 13/30] [Validator] Fix a bug in setOptions --- src/AbstractValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AbstractValidator.php b/src/AbstractValidator.php index 6ef3a4f65..82ae6e557 100644 --- a/src/AbstractValidator.php +++ b/src/AbstractValidator.php @@ -150,7 +150,7 @@ public function setOptions($options = array()) } elseif (($fname2 != 'setOptions') && method_exists($this, $fname2)) { $this->{$fname2}($option); } elseif (isset($this->options)) { - $this->options[$name] = $options; + $this->options[$name] = $option; } else { $this->abstractOptions[$name] = $options; } From 6280c3addcfa91ec377ab91fc3157a624ac0de4a Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 25 Jun 2012 20:11:10 +0200 Subject: [PATCH 14/30] [Validator] Add support for IPvFuture and literal format Add support to IPvFuture as described in RFC 3986 Add support for IPs in literal format --- src/Ip.php | 119 +++++++++-------- test/IpTest.php | 330 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 286 insertions(+), 163 deletions(-) diff --git a/src/Ip.php b/src/Ip.php index 6f2f5aed9..43cd892d0 100644 --- a/src/Ip.php +++ b/src/Ip.php @@ -43,51 +43,17 @@ class Ip extends AbstractValidator ); /** - * internal options + * Internal options * * @var array */ - protected $localOptions = array( - 'allowipv4' => true, - 'allowipv6' => true, + protected $options = array( + 'allowipv4' => true, // Enable IPv4 Validation + 'allowipv6' => true, // Enable IPv6 Validation + 'allowipvfuture' => false, // Enable IPvFuture Validation + 'allowliteral' => true, // Enable IPs in literal format (only IPv6 and IPvFuture) ); - /** - * Sets validator options - * - * @param array|Traversable $options OPTIONAL Options to set, see the manual for all available options - */ - public function __construct($options = array()) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (!is_array($options)) { - $options = func_get_args(); - $temp['allowipv6'] = array_shift($options); - if (!empty($options)) { - $temp['allowipv4'] = array_shift($options); - } - - $options = $temp; - } - - $options += $this->localOptions; - $this->setOptions($options); - - parent::__construct(); - } - - /** - * Returns all set options - * - * @return array - */ - public function getOptions() - { - return $this->localOptions; - } - /** * Sets the options for this validator * @@ -97,23 +63,13 @@ public function getOptions() */ public function setOptions($options = array()) { - if (!is_array($options) && !$options instanceof Traversable) { - throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable'); - } + parent::setOptions($options); - if (array_key_exists('allowipv6', $options)) { - $this->localOptions['allowipv6'] = (boolean) $options['allowipv6']; - } - - if (array_key_exists('allowipv4', $options)) { - $this->localOptions['allowipv4'] = (boolean) $options['allowipv4']; - } - - if (!$this->localOptions['allowipv4'] && !$this->localOptions['allowipv6']) { + if (!$this->options['allowipv4'] && !$this->options['allowipv6'] && !$this->options['allowipvfuture']) { throw new Exception\InvalidArgumentException('Nothing to validate. Check your options'); } - return parent::setOptions($options); + return $this; } /** @@ -130,14 +86,26 @@ public function isValid($value) } $this->setValue($value); - if (($this->localOptions['allowipv4'] && !$this->localOptions['allowipv6'] && !$this->validateIPv4($value)) || - (!$this->localOptions['allowipv4'] && $this->localOptions['allowipv6'] && !$this->validateIPv6($value)) || - ($this->localOptions['allowipv4'] && $this->localOptions['allowipv6'] && !$this->validateIPv4($value) && !$this->validateIPv6($value))) { - $this->error(self::NOT_IP_ADDRESS); - return false; - } - return true; + if ($this->options['allowipv4'] && $this->validateIPv4($value)) { + return true; + } else { + if ((bool) $this->options['allowliteral']) { + var_dump($value,$this->options['allowliteral']); + static $regex = '/^\[(.*)\]$/'; + if ((bool) preg_match($regex, $value, $matches)) { + $value = $matches[1]; + } + } + + if (($this->options['allowipv6'] && $this->validateIPv6($value)) || + ($this->options['allowipvfuture'] && $this->validateIPvFuture($value)) + ) { + return true; + } + } + $this->error(self::NOT_IP_ADDRESS); + return false; } /** @@ -163,7 +131,7 @@ protected function validateIPv4($value) } $ip2long = ip2long($value); - if($ip2long === false) { + if ($ip2long === false) { return false; } @@ -208,4 +176,33 @@ protected function validateIPv6($value) return false; } + + /** + * Validates an IPvFuture address. + * + * IPvFuture is loosely defined in the Section 3.2.2 of RFC 3986 + * + * @param string $value Value to check against + * @return boolean True when $value is a valid IPvFuture address + * False otherwise + */ + protected function validateIPvFuture($value) + { + /* + * ABNF: + * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," + * / ";" / "=" + */ + static $regex = '/^v([[:xdigit:]]+)\.[[:alnum:]\-\._~!\$&\'\(\)\*\+,;=:]+$/'; + + $result = (bool)preg_match($regex, $value, $matches); + + /* + * "As such, implementations must not provide the version flag for the + * existing IPv4 and IPv6 literal address forms described below." + */ + return ($result && $matches[1] != 4 && $matches[1] != 6); + } } \ No newline at end of file diff --git a/test/IpTest.php b/test/IpTest.php index d94ff0179..1cc2f3fac 100644 --- a/test/IpTest.php +++ b/test/IpTest.php @@ -38,6 +38,14 @@ class IpTest extends \PHPUnit_Framework_TestCase */ protected $validator; + /** + * The list with the options supported. + * By default all options are disabled. + * + * @var array + */ + protected $options; + /** * Creates a new IP Validator for each test * @@ -46,6 +54,12 @@ class IpTest extends \PHPUnit_Framework_TestCase public function setUp() { $this->validator = new Ip(); + $this->options = array( + 'allowipv4' => false, + 'allowipv6' => false, + 'allowipvfuture' => false, + 'allowliteral' => false, + ); } /** @@ -68,34 +82,75 @@ public function testZeroIpForZF2420() $this->assertTrue($this->validator->isValid('0.0.0.0')); } - /** - * Ensures that getMessages() returns expected default value - * - * @return void - */ - public function testGetMessages() - { - $this->assertEquals(array(), $this->validator->getMessages()); - } public function testOnlyIpv4() { - $this->validator->setOptions(array('allowipv6' => false)); + $this->options['allowipv4'] = true; + $this->validator->setOptions($this->options); $this->assertTrue($this->validator->isValid('1.2.3.4')); $this->assertFalse($this->validator->isValid('a:b:c:d:e::1.2.3.4')); + $this->assertFalse($this->validator->isValid('v1.09azAZ-._~!$&\'()*+,;=')); } public function testOnlyIpv6() { - $this->validator->setOptions(array('allowipv4' => false)); + $this->options['allowipv6'] = true; + $this->validator->setOptions($this->options); $this->assertFalse($this->validator->isValid('1.2.3.4')); $this->assertTrue($this->validator->isValid('a:b:c:d:e::1.2.3.4')); + $this->assertFalse($this->validator->isValid('v1.09azAZ-._~!$&\'()*+,;=')); + } + + public function testOnlyIpvfuture() + { + $this->options['allowipvfuture'] = true; + $this->validator->setOptions($this->options); + $this->assertFalse($this->validator->isValid('1.2.3.4')); + $this->assertFalse($this->validator->isValid('a:b:c:d:e::1.2.3.4')); + $this->assertTrue($this->validator->isValid("v1.09azAZ-._~!$&'()*+,;=:")); + } + + public function testLiteral() + { + $this->options = array( + 'allowipv4' => true, + 'allowipv6' => true, + 'allowipvfuture' => true, + 'allowliteral' => true, + ); + $this->validator->setOptions($this->options); + + $this->assertFalse($this->validator->isValid('[1.2.3.4]')); + $this->assertTrue($this->validator->isValid('[a:b:c:d:e::1.2.3.4]')); + $this->assertFalse($this->validator->isValid('[[a:b:c:d:e::1.2.3.4]]')); + $this->assertFalse($this->validator->isValid('[[a:b:c:d:e::1.2.3.4]')); + $this->assertFalse($this->validator->isValid('[[a:b:c:d:e::1.2.3.4')); + $this->assertFalse($this->validator->isValid('[a:b:c:d:e::1.2.3.4]]')); + $this->assertFalse($this->validator->isValid('a:b:c:d:e::1.2.3.4]]')); + $this->assertTrue($this->validator->isValid("[v1.ZZ:ZZ]")); + } + + /** + * Versions 4 and 6 are not allowed in IPvFuture + * + * @depends testOnlyIpvfuture + */ + public function testVersionsAllowedIpvfuture() + { + $this->options['allowipvfuture'] = true; + $this->validator->setOptions($this->options); + $this->assertTrue($this->validator->isValid('v1.A', 'IPvFuture: Version 1 disallowed')); + $this->assertTrue($this->validator->isValid('vD.A', 'IPvFuture: Version D disallowed')); + $this->assertTrue($this->validator->isValid('v46.A', 'IPvFuture: Version 46 disallowed')); + + $this->assertFalse($this->validator->isValid('v4.A', 'IPvFuture: Version 4 allowed')); + $this->assertFalse($this->validator->isValid('v6.A', 'IPvFuture: Version 6 allowed')); } public function testNoValidation() { $this->setExpectedException('Zend\Validator\Exception\InvalidArgumentException', 'Nothing to validate'); - $this->validator->setOptions(array('allowipv4' => false, 'allowipv6' => false)); + $this->validator->setOptions($this->options); } public function testInvalidIpForZF4809() @@ -114,90 +169,94 @@ public function testInvalidIpForZF3435() */ public function testIPv6addresses() { - $IPs = array( - '2001:0db8:0000:0000:0000:0000:1428:57ab' => true, - '2001:0DB8:0000:0000:0000:0000:1428:57AB' => true, - '2001:00db8:0000:0000:0000:0000:1428:57ab' => false, - '2001:0db8:xxxx:0000:0000:0000:1428:57ab' => false, - - '2001:db8::1428:57ab' => true, - '2001:db8::1428::57ab' => false, - '2001:dx0::1234' => false, - '2001:db0::12345' => false, - - '' => false, - ':' => false, - '::' => true, - ':::' => false, - '::::' => false, - '::1' => true, - ':::1' => false, - - '::1.2.3.4' => true, - '::127.0.0.1' => true, - '::256.0.0.1' => false, - '::01.02.03.04' => true, + $ips = array( + '2001:0db8:0000:0000:0000:0000:1428:57ab' => true, + '2001:0DB8:0000:0000:0000:0000:1428:57AB' => true, + '[2001:0DB8:0000:0000:0000:0000:1428:57AB]' => true, + '2001:00db8:0000:0000:0000:0000:1428:57ab' => false, + '2001:0db8:xxxx:0000:0000:0000:1428:57ab' => false, + '2001:0DB8:0000:0000:0000:0000:1428:57AB:90' => false, + '[2001:0DB8:0000:0000:0000:0000:1428:57AB]:90' => false, + + '2001:db8::1428:57ab' => true, + '2001:db8::1428::57ab' => false, + '2001:dx0::1234' => false, + '2001:db0::12345' => false, + + '' => false, + ':' => false, + '::' => true, + ':::' => false, + '::::' => false, + '::1' => true, + ':::1' => false, + + '[::1.2.3.4]' => true, + '::1.2.3.4' => true, + '::127.0.0.1' => true, + '::256.0.0.1' => false, + '::01.02.03.04' => true, // according to RFC this can be interpreted as hex notation IPv4 - 'a:b:c::1.2.3.4' => true, - 'a:b:c:d::1.2.3.4' => true, - 'a:b:c:d:e::1.2.3.4' => true, - 'a:b:c:d:e:f:1.2.3.4' => true, - 'a:b:c:d:e:f:1.256.3.4' => false, - 'a:b:c:d:e:f::1.2.3.4' => false, - - 'a:b:c:d:e:f:0:1:2' => false, - 'a:b:c:d:e:f:0:1' => true, - 'a::b:c:d:e:f:0:1' => false, - 'a::c:d:e:f:0:1' => true, - 'a::d:e:f:0:1' => true, - 'a::e:f:0:1' => true, - 'a::f:0:1' => true, - 'a::0:1' => true, - 'a::1' => true, - 'a::' => true, - - '::0:1:a:b:c:d:e:f' => false, - '::0:a:b:c:d:e:f' => true, - '::a:b:c:d:e:f' => true, - '::b:c:d:e:f' => true, - '::c:d:e:f' => true, - '::d:e:f' => true, - '::e:f' => true, - '::f' => true, - - '0:1:a:b:c:d:e:f::' => false, - '0:a:b:c:d:e:f::' => true, - 'a:b:c:d:e:f::' => true, - 'b:c:d:e:f::' => true, - 'c:d:e:f::' => true, - 'd:e:f::' => true, - 'e:f::' => true, - 'f::' => true, - - 'a:b:::e:f' => false, - '::a:' => false, - '::a::' => false, - ':a::b' => false, - 'a::b:' => false, - '::a:b::c' => false, - 'abcde::f' => false, - - ':10.0.0.1' => false, - '0:0:0:255.255.255.255' => false, - '1fff::a88:85a3::172.31.128.1' => false, - - 'a:b:c:d:e:f:0::1' => false, - 'a:b:c:d:e:f:0::' => true, - 'a:b:c:d:e:f::0' => true, - - 'total gibberish' => false + 'a:b:c::1.2.3.4' => true, + 'a:b:c:d::1.2.3.4' => true, + 'a:b:c:d:e::1.2.3.4' => true, + 'a:b:c:d:e:f:1.2.3.4' => true, + 'a:b:c:d:e:f:1.256.3.4' => false, + 'a:b:c:d:e:f::1.2.3.4' => false, + + 'a:b:c:d:e:f:0:1:2' => false, + 'a:b:c:d:e:f:0:1' => true, + 'a::b:c:d:e:f:0:1' => false, + 'a::c:d:e:f:0:1' => true, + 'a::d:e:f:0:1' => true, + 'a::e:f:0:1' => true, + 'a::f:0:1' => true, + 'a::0:1' => true, + 'a::1' => true, + 'a::' => true, + + '::0:1:a:b:c:d:e:f' => false, + '::0:a:b:c:d:e:f' => true, + '::a:b:c:d:e:f' => true, + '::b:c:d:e:f' => true, + '::c:d:e:f' => true, + '::d:e:f' => true, + '::e:f' => true, + '::f' => true, + + '0:1:a:b:c:d:e:f::' => false, + '0:a:b:c:d:e:f::' => true, + 'a:b:c:d:e:f::' => true, + 'b:c:d:e:f::' => true, + 'c:d:e:f::' => true, + 'd:e:f::' => true, + 'e:f::' => true, + 'f::' => true, + + 'a:b:::e:f' => false, + '::a:' => false, + '::a::' => false, + ':a::b' => false, + 'a::b:' => false, + '::a:b::c' => false, + 'abcde::f' => false, + + ':10.0.0.1' => false, + '0:0:0:255.255.255.255' => false, + '1fff::a88:85a3::172.31.128.1' => false, + + 'a:b:c:d:e:f:0::1' => false, + 'a:b:c:d:e:f:0::' => true, + 'a:b:c:d:e:f::0' => true, + + 'total gibberish' => false ); - foreach ($IPs as $ip => $expectedOutcome) { + foreach ($ips as $ip => $expectedOutcome) { if ($expectedOutcome) { - $this->assertTrue($this->validator->isValid($ip), $ip . ' failed validation'); + $this->assertTrue($this->validator->isValid($ip), $ip . ' failed validation (expects true)'); } else { - $this->assertFalse($this->validator->isValid($ip), $ip . ' failed validation'); + $this->assertFalse($this->validator->isValid($ip), $ip . ' failed validation (expects false)'); } } @@ -226,28 +285,95 @@ public function testIPv4AddressNotations() { $ips = array( // binary notation - '00000001.00000010.00000011.00000100' => true, - '10000000.02000000.00000000.00000001' => false, + '00000001.00000010.00000011.00000100' => true, + '10000000.02000000.00000000.00000001' => false, + '10000000.02000000.00000000.00000001:80' => false, // octal notation (always seen as integer!) - '001.002.003.004' => true, - '009.008.007.006' => true, - '0a0.100.001.010' => false, + '001.002.003.004' => true, + '009.008.007.006' => true, + '0a0.100.001.010' => false, + '0a0.100.001.010:80' => false, // hex notation - '01.02.03.04' => true, - 'a0.b0.c0.d0' => true, - 'g0.00.00.00' => false + '01.02.03.04' => true, + 'a0.b0.c0.d0' => true, + 'g0.00.00.00' => false, + 'g0.00.00.00:80' => false, ); foreach ($ips as $ip => $expectedOutcome) { if ($expectedOutcome) { - $this->assertTrue($this->validator->isValid($ip), $ip . ' failed validation'); + $this->assertTrue($this->validator->isValid($ip), $ip . ' failed validation (expects true)'); } else { - $this->assertFalse($this->validator->isValid($ip), $ip . ' failed validation'); + $this->assertFalse($this->validator->isValid($ip), $ip . ' failed validation (expects false)'); } } + } + + /** + * @dataProvider iPvFutureAddressesProvider + */ + public function testIPvFutureAddresses($ip, $expected) + { + $this->options['allowipvfuture'] = true; + $this->options['allowliteral'] = true; + $this->validator->setOptions($this->options); + $this->assertEquals($expected, $this->validator->isValid($ip)); + } + public function iPvFutureAddressesProvider() + { + return array( + array("[v1.09azAZ-._~!$&'()*+,;=:]:80", false), + array("[v1.09azAZ-._~!$&'()*+,;=:]", true), + array("[v1.09azAZ-._~!$&'()*+,;=:", false), + array("v1.09azAZ-._~!$&'()*+,;=:]", false), + array("v1.09azAZ-._~!$&'()*+,;=:", true), + array("v1.09azAZ-._~!$&'()*+,;=", true), + array("v1.09azAZ-._~!$&'()*+,;", true), + array("v1.09azAZ-._~!$&'()*+,", true), + array("v1.09azAZ-._~!$&'()*+", true), + array("v1.09azAZ-._~!$&'()*", true), + array("v1.09azAZ-._~!$&'()", true), + array("v1.09azAZ-._~!$&'(", true), + array("v1.09azAZ-._~!$&'", true), + array("v1.09azAZ-._~!$&", true), + array("v1.09azAZ-._~!$", true), + array("v1.09azAZ-._~!", true), + array("v1.09azAZ-._~", true), + array("v1.09azAZ-._", true), + array("v1.09azAZ-.", true), + array("v1.09azAZ-", true), + array("v1.09azAZ", true), + array("v1.09azA", true), + array("v1.09az", true), + array("v1.09a", true), + array("v1.09", true), + array("v1.0", true), + array("v1.", false), + array("v1", false), + array("v", false), + array("", false), + array("vFF.Z", true), + array("vFG./", false), + array("v1./", false), + array("v1.?", false), + array("v1.#", false), + array("v1.[", false), + array("v1.]", false), + array("v1.@", false), + ); + } + + /** + * Ensures that getMessages() returns expected default value + * + * @return void + */ + public function testGetMessages() + { + $this->assertEquals(array(), $this->validator->getMessages()); } public function testEqualsMessageTemplates() @@ -256,4 +382,4 @@ public function testEqualsMessageTemplates() $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } -} +} \ No newline at end of file From 3684f6b58abf24e1c7717cb76f8fb33b85407966 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Tue, 26 Jun 2012 17:13:12 +0200 Subject: [PATCH 15/30] [Validator] Rework some test for use mock-ups instead of testassets --- src/NotEmpty.php | 2 +- test/AbstractTest.php | 25 ++----- test/NotEmptyTest.php | 7 +- test/TestAsset/ConcreteValidator.php | 40 +++++++++++ ...alidateTest.php => ValidatorChainTest.php} | 69 ++++++++----------- 5 files changed, 78 insertions(+), 65 deletions(-) create mode 100644 test/TestAsset/ConcreteValidator.php rename test/{ValidateTest.php => ValidatorChainTest.php} (79%) diff --git a/src/NotEmpty.php b/src/NotEmpty.php index ad3ae723e..763e4955d 100644 --- a/src/NotEmpty.php +++ b/src/NotEmpty.php @@ -84,7 +84,7 @@ class NotEmpty extends AbstractValidator /** * Constructor * - * @param array|Traversable $options OPTIONAL + * @param array|Traversable|int $options OPTIONAL */ public function __construct($options = null) { diff --git a/test/AbstractTest.php b/test/AbstractTest.php index f1495a662..8c4e3ba2c 100644 --- a/test/AbstractTest.php +++ b/test/AbstractTest.php @@ -46,7 +46,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->validator = new Concrete(); + $this->validator = new TestAsset\ConcreteValidator(); } public function testTranslatorNullByDefault() @@ -188,14 +188,14 @@ public function testGetMessageTemplates() array('fooMessage' => '%value% was passed'), $messages); $this->assertEquals( - array(Concrete::FOO_MESSAGE => '%value% was passed'), + array(TestAsset\ConcreteValidator::FOO_MESSAGE => '%value% was passed'), $messages ); } public function testInvokeProxiesToIsValid() { - $validator = new Concrete; + $validator = new TestAsset\ConcreteValidator; $this->assertFalse($validator('foo')); $this->assertContains("foo was passed", $validator->getMessages()); } @@ -214,21 +214,4 @@ public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $e { $this->errorOccurred = true; } -} - -class Concrete extends AbstractValidator -{ - const FOO_MESSAGE = 'fooMessage'; - - protected $messageTemplates = array( - 'fooMessage' => '%value% was passed', - ); - - public function isValid($value) - { - $this->setValue($value); - $this->error(self::FOO_MESSAGE); - return false; - } -} - +} \ No newline at end of file diff --git a/test/NotEmptyTest.php b/test/NotEmptyTest.php index 18ab929d2..3ef96ab9f 100644 --- a/test/NotEmptyTest.php +++ b/test/NotEmptyTest.php @@ -21,6 +21,7 @@ namespace ZendTest\Validator; +use stdClass; use Zend\Validator\NotEmpty; /** @@ -546,7 +547,7 @@ public function testZF8767() public function testObjects() { $valid = new NotEmpty(NotEmpty::STRING); - $object = new ClassTest1(); + $object = new stdClass(); $this->assertFalse($valid->isValid($object)); @@ -603,8 +604,6 @@ public function testEqualsMessageTemplates() } } -class ClassTest1 {} - class ClassTest2 { public function __toString() @@ -619,4 +618,4 @@ public function toString() { return ''; } -} +} \ No newline at end of file diff --git a/test/TestAsset/ConcreteValidator.php b/test/TestAsset/ConcreteValidator.php new file mode 100644 index 000000000..c58032482 --- /dev/null +++ b/test/TestAsset/ConcreteValidator.php @@ -0,0 +1,40 @@ + '%value% was passed', + ); + + public function isValid($value) + { + $this->setValue($value); + $this->error(self::FOO_MESSAGE); + return false; + } +} \ No newline at end of file diff --git a/test/ValidateTest.php b/test/ValidatorChainTest.php similarity index 79% rename from test/ValidateTest.php rename to test/ValidatorChainTest.php index 7db15f2bf..b2c64ac16 100644 --- a/test/ValidateTest.php +++ b/test/ValidatorChainTest.php @@ -34,11 +34,9 @@ * @license http://framework.zend.com/license/new-bsd New BSD License * @group Zend_Validator */ -class ValidatorTest extends \PHPUnit_Framework_TestCase +class ValidatorChainTest extends \PHPUnit_Framework_TestCase { /** - * Zend_Validator object - * * @var ValidatorChain */ protected $validator; @@ -50,11 +48,6 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase */ protected $errorOccurred = false; - /** - * Creates a new Zend_Validator object for each test method - * - * @return void - */ public function setUp() { $this->validator = new ValidatorChain(); @@ -78,7 +71,7 @@ public function testEmpty() */ public function testTrue() { - $this->validator->addValidator(new ValidatorTrue()); + $this->validator->addValidator($this->getValidatorTrue()); $this->assertTrue($this->validator->isValid(null)); $this->assertEquals(array(), $this->validator->getMessages()); } @@ -90,7 +83,7 @@ public function testTrue() */ public function testFalse() { - $this->validator->addValidator(new ValidatorFalse()); + $this->validator->addValidator($this->getValidatorFalse()); $this->assertFalse($this->validator->isValid(null)); $this->assertEquals(array('error' => 'validation failed'), $this->validator->getMessages()); } @@ -102,8 +95,8 @@ public function testFalse() */ public function testBreakChainOnFailure() { - $this->validator->addValidator(new ValidatorFalse(), true) - ->addValidator(new ValidatorFalse()); + $this->validator->addValidator($this->getValidatorFalse(), true) + ->addValidator($this->getValidatorFalse()); $this->assertFalse($this->validator->isValid(null)); $this->assertEquals(array('error' => 'validation failed'), $this->validator->getMessages()); } @@ -151,8 +144,8 @@ public function testSetGetDefaultTranslator() public function testAllowsPrependingValidators() { - $this->validator->addValidator(new ValidatorTrue()) - ->prependValidator(new ValidatorFalse(), true); + $this->validator->addValidator($this->getValidatorTrue()) + ->prependValidator($this->getValidatorFalse(), true); $this->assertFalse($this->validator->isValid(true)); $messages = $this->validator->getMessages(); $this->assertArrayHasKey('error', $messages); @@ -160,7 +153,7 @@ public function testAllowsPrependingValidators() public function testAllowsPrependingValidatorsByName() { - $this->validator->addValidator(new ValidatorTrue()) + $this->validator->addValidator($this->getValidatorTrue()) ->prependByName('NotEmpty', array(), true); $this->assertFalse($this->validator->isValid('')); $messages = $this->validator->getMessages(); @@ -196,33 +189,31 @@ public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $e { $this->errorOccurred = true; } -} - -/** - * Validator to return true to any input. - */ -class ValidatorTrue extends AbstractValidator -{ - public function isValid($value) + /** + * @return \PHPUnit_Framework_MockObject_MockObject|\Zend\Validator\ValidatorInterface + */ + public function getValidatorTrue() { - return true; + $validator = $this->getMock('Zend\Validator\ValidatorInterface'); + $validator->expects($this->any()) + ->method('isValid') + ->will($this->returnValue(true)); + return $validator; } -} - -/** - * Validator to return false to any input. - */ -class ValidatorFalse extends AbstractValidator -{ - protected $messageTemplates = array( - 'error' => 'validation failed', - ); - - public function isValid($value) + /** + * @return \PHPUnit_Framework_MockObject_MockObject|\Zend\Validator\ValidatorInterface + */ + public function getValidatorFalse() { - $this->error('error'); - return false; + $validator = $this->getMock('Zend\Validator\ValidatorInterface'); + $validator->expects($this->any()) + ->method('isValid') + ->will($this->returnValue(false)); + $validator->expects($this->any()) + ->method('getMessages') + ->will($this->returnValue(array('error' => 'validation failed'))); + return $validator; } -} +} \ No newline at end of file From 9262db1d2dc8789b3d87ae1089af869713393705 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 27 Jun 2012 12:30:19 -0500 Subject: [PATCH 16/30] [zendframework/zf2#1590] Removed var_dump --- src/Ip.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Ip.php b/src/Ip.php index 43cd892d0..7bdae9394 100644 --- a/src/Ip.php +++ b/src/Ip.php @@ -91,7 +91,6 @@ public function isValid($value) return true; } else { if ((bool) $this->options['allowliteral']) { - var_dump($value,$this->options['allowliteral']); static $regex = '/^\[(.*)\]$/'; if ((bool) preg_match($regex, $value, $matches)) { $value = $matches[1]; @@ -205,4 +204,4 @@ protected function validateIPvFuture($value) */ return ($result && $matches[1] != 4 && $matches[1] != 6); } -} \ No newline at end of file +} From 760bfc0593d305d2d84f2520ffe1c443682a8d7d Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 26 Jun 2012 17:28:52 -0500 Subject: [PATCH 17/30] Refactored Zend\Registry to remove singleton - Registry no longer has singleton capabilities - get() now allows passing a default value - Refactored all classes and tests using Registry - Most simply checked registry for an object; removed such checks - Others stored themselves inside Registry; made those implement singletons (and gave them methods for removing singleton instances) --- src/AbstractValidator.php | 13 +------------ src/Date.php | 7 ------- src/Iban.php | 7 ------- src/Int.php | 6 ------ src/PostCode.php | 11 +++-------- test/DateTest.php | 7 ++----- test/FloatTest.php | 21 +++------------------ test/IbanTest.php | 8 +------- test/IntTest.php | 5 ++--- test/StaticValidatorTest.php | 26 ++++++-------------------- 10 files changed, 18 insertions(+), 93 deletions(-) diff --git a/src/AbstractValidator.php b/src/AbstractValidator.php index 82ae6e557..4ef2f2b52 100644 --- a/src/AbstractValidator.php +++ b/src/AbstractValidator.php @@ -478,17 +478,6 @@ public static function setDefaultTranslator($translator = null) */ public static function getDefaultTranslator() { - if (null === self::$defaultTranslator) { - if (Registry::isRegistered('Zend_Translator')) { - $translator = Registry::get('Zend_Translator'); - if ($translator instanceof Translator\Adapter\AbstractAdapter) { - return $translator; - } elseif ($translator instanceof Translator\Translator) { - return $translator->getAdapter(); - } - } - } - return self::$defaultTranslator; } @@ -543,4 +532,4 @@ public static function setMessageLength($length = -1) { self::$messageLength = $length; } -} \ No newline at end of file +} diff --git a/src/Date.php b/src/Date.php index 96742b930..541a2bbba 100644 --- a/src/Date.php +++ b/src/Date.php @@ -24,7 +24,6 @@ use Zend\Date as ZendDate; use Zend\Locale\Format; use Zend\Locale\Locale; -use Zend\Registry; use Zend\Stdlib\ArrayUtils; /** @@ -94,12 +93,6 @@ public function __construct($options = array()) $this->setFormat($options['format']); } - if (!array_key_exists('locale', $options)) { - if (Registry::isRegistered('Zend_Locale')) { - $options['locale'] = Registry::get('Zend_Locale'); - } - } - if (array_key_exists('locale', $options)) { $this->setLocale($options['locale']); } diff --git a/src/Iban.php b/src/Iban.php index 0463cdcae..1b7a6d687 100644 --- a/src/Iban.php +++ b/src/Iban.php @@ -22,7 +22,6 @@ use Traversable; use Zend\Locale\Locale; -use Zend\Registry; use Zend\Stdlib\ArrayUtils; /** @@ -124,12 +123,6 @@ public function __construct($options = null) } } - if (empty($options) && ($options !== false)) { - if (Registry::isRegistered('Zend_Locale')) { - $options = Registry::get('Zend_Locale'); - } - } - if ($options !== null) { $this->setLocale($options); } diff --git a/src/Int.php b/src/Int.php index 0d433699d..c74552d95 100644 --- a/src/Int.php +++ b/src/Int.php @@ -65,12 +65,6 @@ public function __construct($options = null) } } - if (empty($options)) { - if (Registry::isRegistered('Zend_Locale')) { - $options = Registry::get('Zend_Locale'); - } - } - if ($options !== null) { $this->setLocale($options); } diff --git a/src/PostCode.php b/src/PostCode.php index 7e8832678..8b297afa4 100644 --- a/src/PostCode.php +++ b/src/PostCode.php @@ -24,9 +24,6 @@ use Zend\Registry; /** - * @see Zend_Locale - * @see Zend_Locale_Format - * @see Zend_Registry * @category Zend * @package Zend_Validate * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) @@ -71,11 +68,9 @@ class PostCode extends AbstractValidator */ public function __construct($options = null) { - if (empty($options)) { - if (Registry::isRegistered('Zend_Locale')) { - $this->setLocale(Registry::get('Zend_Locale')); - } - } elseif ($options instanceof Locale\Locale || is_string($options)) { + if (!empty($options) + && ($options instanceof Locale\Locale || is_string($options)) + ) { // Received Locale object or string locale $this->setLocale($options); } diff --git a/test/DateTest.php b/test/DateTest.php index ab949b888..af6be9bf9 100644 --- a/test/DateTest.php +++ b/test/DateTest.php @@ -23,7 +23,6 @@ use Zend\Validator\Date as DateValidator; use Zend\Date; -use Zend\Registry; /** * @category Zend @@ -49,7 +48,6 @@ class DateTest extends \PHPUnit_Framework_TestCase public function setUp() { - Registry::_unsetInstance(); $this->errorOccurred = false; $this->validator = new DateValidator(); } @@ -203,14 +201,13 @@ public function testNonStringValidation() */ public function testUsingApplicationLocale() { - \Zend\Registry::set('Zend_Locale', new \Zend\Locale\Locale('de')); + $this->markTestSkipped('Depends on system-specific locale'); $valid = new DateValidator(); $this->assertTrue($valid->isValid('10.April.2008')); } /** - * @group fml - * ZF-7630 + * @group ZF-7630 */ public function testDateObjectVerification() { diff --git a/test/FloatTest.php b/test/FloatTest.php index eacf5e4dc..0437775f4 100644 --- a/test/FloatTest.php +++ b/test/FloatTest.php @@ -42,12 +42,7 @@ class FloatTest extends \PHPUnit_Framework_TestCase protected $locale; public function setUp() { - $this->locale = setlocale(LC_ALL, 0); //backup locale - - if (\Zend\Registry::isRegistered('Zend_Locale')) { - \Zend\Registry::getInstance()->offsetUnset('Zend_Locale'); - } - + $this->locale = setlocale(LC_ALL, 0); //backup locale $this->validator = new FloatValidator(); } @@ -110,23 +105,13 @@ public function testSettingLocales() } /** - * @ZF-4352 + * @group ZF-4352 */ public function testNonStringValidation() { $this->assertFalse($this->validator->isValid(array(1 => 1))); } - /** - * @ZF-7489 - */ - public function testUsingApplicationLocale() - { - \Zend\Registry::set('Zend_Locale', new \Zend\Locale\Locale('de')); - $valid = new FloatValidator(); - $this->assertTrue($valid->isValid('123,456')); - } - /** * @ZF-7987 */ @@ -218,4 +203,4 @@ public function testEqualsMessageTemplates() $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } -} \ No newline at end of file +} diff --git a/test/IbanTest.php b/test/IbanTest.php index 0f3950a8e..2fb8f16b3 100644 --- a/test/IbanTest.php +++ b/test/IbanTest.php @@ -21,7 +21,6 @@ namespace ZendTest\Validator; -use Zend\Registry; use Zend\Validator\Iban; /** @@ -34,11 +33,6 @@ */ class IbanTest extends \PHPUnit_Framework_TestCase { - public function setUp() - { - Registry::_unsetInstance(); - } - /** * Ensures that the validator follows expected behavior * @@ -98,4 +92,4 @@ public function testEqualsMessageTemplates() $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } -} \ No newline at end of file +} diff --git a/test/IntTest.php b/test/IntTest.php index ef5bb165c..94e746bb7 100644 --- a/test/IntTest.php +++ b/test/IntTest.php @@ -105,7 +105,6 @@ public function testNonStringValidation() */ public function testUsingApplicationLocale() { - \Zend\Registry::set('Zend_Locale', new Locale\Locale('de')); $valid = new Int(); $this->assertTrue($valid->isValid('10.000')); } @@ -115,7 +114,7 @@ public function testUsingApplicationLocale() */ public function testLocaleDetectsNoEnglishLocaleOnOtherSetLocale() { - \Zend\Registry::set('Zend_Locale', new Locale\Locale('de')); + $this->markTestSkipped('Depends on system-specific locale'); $valid = new Int(); $this->assertTrue($valid->isValid(1200)); $this->assertFalse($valid->isValid('1,200')); @@ -127,4 +126,4 @@ public function testEqualsMessageTemplates() $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } -} \ No newline at end of file +} diff --git a/test/StaticValidatorTest.php b/test/StaticValidatorTest.php index 5d5adffb4..9d17ece30 100644 --- a/test/StaticValidatorTest.php +++ b/test/StaticValidatorTest.php @@ -48,17 +48,13 @@ class StaticValidatorTest extends \PHPUnit_Framework_TestCase */ protected $errorOccurred = false; - public function clearRegistry() - { - if (\Zend\Registry::isRegistered('Zend_Translator')) { - $registry = \Zend\Registry::getInstance(); - unset($registry['Zend_Translator']); - } - } - + /** + * Creates a new validation object for each test method + * + * @return void + */ public function setUp() { - $this->clearRegistry(); AbstractValidator::setDefaultTranslator(null); StaticValidator::setPluginManager(null); $this->validator = new Alpha(); @@ -66,7 +62,6 @@ public function setUp() public function tearDown() { - $this->clearRegistry(); AbstractValidator::setDefaultTranslator(null); AbstractValidator::setMessageLength(-1); } @@ -101,15 +96,6 @@ public function testGlobalDefaultTranslatorUsedWhenNoLocalTranslatorSet() $this->assertSame(AbstractValidator::getDefaultTranslator(), $this->validator->getTranslator()); } - public function testGlobalTranslatorFromRegistryUsedWhenNoLocalTranslatorSet() - { - set_error_handler(array($this, 'errorHandlerIgnore')); - $translate = new Translator\Translator('ArrayAdapter', array()); - restore_error_handler(); - \Zend\Registry::set('Zend_Translator', $translate); - $this->assertSame($translate->getAdapter(), $this->validator->getTranslator()); - } - public function testLocalTranslatorPreferredOverGlobalTranslator() { $this->testCanSetGlobalDefaultTranslator(); @@ -187,4 +173,4 @@ public function testExecuteValidWithParameters() $this->assertTrue(StaticValidator::execute(5, 'Between', array(1, 10))); $this->assertTrue(StaticValidator::execute(5, 'Between', array('min' => 1, 'max' => 10))); } -} \ No newline at end of file +} From a3c5af0f0817864b4b4df5bbb7dd8b1be1c029f9 Mon Sep 17 00:00:00 2001 From: Yanick Rochon Date: Wed, 27 Jun 2012 20:09:48 -0400 Subject: [PATCH 18/30] The initCsrfToken method in the CSRF validator was made protected because it was redundant; the getHash method has now an optional boolean argument to force regenerate a new hash to validate. The CSRF form element now regenerates a new hash on prepare. --- src/Csrf.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Csrf.php b/src/Csrf.php index 959ff520c..39a8c86c7 100644 --- a/src/Csrf.php +++ b/src/Csrf.php @@ -216,14 +216,20 @@ public function getSalt() /** * Retrieve CSRF token * - * If no CSRF token currently exists, generates one. + * If no CSRF token currently exists, or should be regenrated, + * generates one. * + * @param bool $regenerate default false * @return string */ - public function getHash() + public function getHash($regenerate = false) { - if (null === $this->hash) { - $this->hash = $this->getValidationToken(); + if ((null === $this->hash) || $regenerate) { + if ($regenerate) { + $this->hash = null; + } else { + $this->hash = $this->getValidationToken(); + } if (null === $this->hash) { $this->generateHash(); } @@ -270,7 +276,7 @@ public function getTimeout() * * @return void */ - public function initCsrfToken() + protected function initCsrfToken() { $session = $this->getSession(); //$session->setExpirationHops(1, null, true); From da0c1e911cbc45d366de8d962eed00139add9231 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 29 Jun 2012 14:55:49 -0500 Subject: [PATCH 19/30] [zendframework/zf2#1672] Improvements to API - Removed setValidators(); developers can extend and alter getInputSpec() and/or directly manipulate the input filter if desired. - Made getValidators() protected - Updated tests to reflect the above and test implicit validator creation based on attributes --- src/Step.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Step.php b/src/Step.php index 1601c8ca8..af7e706c6 100644 --- a/src/Step.php +++ b/src/Step.php @@ -21,7 +21,6 @@ namespace Zend\Validator; use Traversable; -use Zend\Stdlib\ArrayUtils; /** * @category Zend @@ -60,7 +59,7 @@ class Step extends AbstractValidator public function __construct($options = array()) { if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); + $options = iterator_to_array($options); } elseif (!is_array($options)) { $options = func_get_args(); $temp['baseValue'] = array_shift($options); From 6c0c1c9e72920d7753669450f6675213100359cf Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 29 Jun 2012 15:04:52 -0500 Subject: [PATCH 20/30] [zendframework/zf2#1588] Brought list up-to-date - Added DateStep and Step validators --- src/ValidatorPluginManager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ValidatorPluginManager.php b/src/ValidatorPluginManager.php index c29e4214f..e3a6c92ff 100644 --- a/src/ValidatorPluginManager.php +++ b/src/ValidatorPluginManager.php @@ -71,6 +71,7 @@ class ValidatorPluginManager extends AbstractPluginManager 'creditcard' => 'Zend\Validator\CreditCard', 'csrf' => 'Zend\Validator\Csrf', 'date' => 'Zend\Validator\Date', + 'datestep' => 'Zend\Validator\DateStep', 'dbnorecordexists' => 'Zend\Validator\Db\NoRecordExists', 'dbrecordexists' => 'Zend\Validator\Db\RecordExists', 'digits' => 'Zend\Validator\Digits', @@ -113,6 +114,7 @@ class ValidatorPluginManager extends AbstractPluginManager 'sitemaploc' => 'Zend\Validator\Sitemap\Loc', 'sitemappriority' => 'Zend\Validator\Sitemap\Priority', 'stringlength' => 'Zend\Validator\StringLength', + 'step' => 'Zend\Validator\Step', ); /** From 1f99de820116a61d79a4b958eb4f71370cd82020 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 29 Jun 2012 15:06:09 -0500 Subject: [PATCH 21/30] [zendframework/zf2#1588] remove underscore prefix - from messageTemplates member --- src/DateStep.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DateStep.php b/src/DateStep.php index 438b628f4..81ed161b4 100644 --- a/src/DateStep.php +++ b/src/DateStep.php @@ -43,7 +43,7 @@ class DateStep extends AbstractValidator /** * @var array */ - protected $_messageTemplates = array( + protected $messageTemplates = array( self::INVALID => "Invalid type given. String, integer, array or Zend_Date expected", self::INVALID_DATE => "'%value%' does not appear to be a valid date", self::NOT_STEP => "'%value%' is not a valid step." From 1ab83e844ede714a159a8a1ba64a28210674399c Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 29 Jun 2012 15:16:31 -0500 Subject: [PATCH 22/30] [zendframework/zf2#1588] Cleanup - Suggested by Maks3w in comments on the PR --- src/DateStep.php | 2 +- test/DateStepTest.php | 44 +++---------------------------------------- 2 files changed, 4 insertions(+), 42 deletions(-) diff --git a/src/DateStep.php b/src/DateStep.php index 81ed161b4..ad8ab028a 100644 --- a/src/DateStep.php +++ b/src/DateStep.php @@ -44,7 +44,7 @@ class DateStep extends AbstractValidator * @var array */ protected $messageTemplates = array( - self::INVALID => "Invalid type given. String, integer, array or Zend_Date expected", + self::INVALID => "Invalid type given. String, integer, array or DateTime expected", self::INVALID_DATE => "'%value%' does not appear to be a valid date", self::NOT_STEP => "'%value%' is not a valid step." ); diff --git a/test/DateStepTest.php b/test/DateStepTest.php index 120873e07..5b8d9b256 100644 --- a/test/DateStepTest.php +++ b/test/DateStepTest.php @@ -25,18 +25,9 @@ use DateTime; use DateTimeZone; use DateInterval; -use ReflectionClass; - -/** - * Test helper - */ - -/** - * @see \Zend\Validator\DateStep - */ - /** + * @see \Zend\Validator\DateStep * @category Zend * @package Zend_Validator * @subpackage UnitTests @@ -127,36 +118,7 @@ public function testGetMessagesReturnsDefaultValue() public function testEqualsMessageTemplates() { $validator = new Validator\DateStep(array()); - $reflection = new ReflectionClass($validator); - - if (!$reflection->hasProperty('_messageTemplates')) { - return; - } - - $property = $reflection->getProperty('_messageTemplates'); - $property->setAccessible(true); - - $this->assertEquals( - $property->getValue($validator), - $validator->getOption('messageTemplates') - ); - } - - public function testEqualsMessageVariables() - { - $validator = new Validator\DateStep(array()); - $reflection = new ReflectionClass($validator); - - if (!$reflection->hasProperty('_messageVariables')) { - return; - } - - $property = $reflection->getProperty('_messageVariables'); - $property->setAccessible(true); - - $this->assertEquals( - $property->getValue($validator), - $validator->getOption('messageVariables') - ); + $this->assertObjectHasAttribute('messageTemplates', $validator); + $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } } From a264b09eb2193a2b8d6972a621dd305afe87bd78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20Gallego?= Date: Fri, 29 Jun 2012 23:38:16 +0200 Subject: [PATCH 23/30] Updated consistency of validators and tests --- src/DateStep.php | 28 ++++++++++++++-------------- test/DateStepTest.php | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/DateStep.php b/src/DateStep.php index ad8ab028a..5808df77c 100644 --- a/src/DateStep.php +++ b/src/DateStep.php @@ -62,7 +62,7 @@ class DateStep extends AbstractValidator * * @var DateInterval */ - protected $stepInterval; + protected $step; /** * Format to use for parsing date strings @@ -92,7 +92,7 @@ public function __construct($options = array()) $options = func_get_args(); $temp['baseValue'] = array_shift($options); if (!empty($options)) { - $temp['stepInterval'] = array_shift($options); + $temp['step'] = array_shift($options); } if (!empty($options)) { $temp['format'] = array_shift($options); @@ -107,10 +107,10 @@ public function __construct($options = array()) if (isset($options['baseValue'])) { $this->setBaseValue($options['baseValue']); } - if (isset($options['stepInterval'])) { - $this->setStepInterval($options['stepInterval']); + if (isset($options['step'])) { + $this->setStep($options['step']); } else { - $this->setStepInterval(new DateInterval('P1D')); + $this->setStep(new DateInterval('P1D')); } if (array_key_exists('format', $options)) { $this->setFormat($options['format']); @@ -149,12 +149,12 @@ public function getBaseValue() /** * Sets the step date interval * - * @param DateInterval $stepValue + * @param DateInterval $step * @return DateStep */ - public function setStepInterval(DateInterval $stepInterval) + public function setStep(DateInterval $step) { - $this->stepInterval = $stepInterval; + $this->step = $step; return $this; } @@ -163,9 +163,9 @@ public function setStepInterval(DateInterval $stepInterval) * * @return DateInterval */ - public function getStepInterval() + public function getStep() { - return $this->stepInterval; + return $this->step; } /** @@ -265,7 +265,7 @@ public function isValid($value) $this->setValue($value); $baseDate = $this->convertToDateTime($this->getBaseValue()); - $stepInterval = $this->getStepInterval(); + $step = $this->getStep(); // Parse the date try { @@ -282,7 +282,7 @@ public function isValid($value) // Optimization for simple intervals. // Handle intervals of just one date or time unit. - $intervalParts = explode('|', $stepInterval->format('%y|%m|%d|%h|%i|%s')); + $intervalParts = explode('|', $step->format('%y|%m|%d|%h|%i|%s')); $partCounts = array_count_values($intervalParts); if (5 === $partCounts["0"]) { // Find the unit with the non-zero interval @@ -398,14 +398,14 @@ public function isValid($value) // or until the value is exceeded. if ($baseDate < $valueDate) { while ($baseDate < $valueDate) { - $baseDate->add($stepInterval); + $baseDate->add($step); if ($baseDate == $valueDate) { return true; } } } else { while ($baseDate > $valueDate) { - $baseDate->sub($stepInterval); + $baseDate->sub($step); if ($baseDate == $valueDate) { return true; } diff --git a/test/DateStepTest.php b/test/DateStepTest.php index 5b8d9b256..b63a366e4 100644 --- a/test/DateStepTest.php +++ b/test/DateStepTest.php @@ -103,7 +103,7 @@ public function testDateStepValidation($interval, $format, $baseValue, $value, $ $validator = new Validator\DateStep(array( 'format' => $format, 'baseValue' => $baseValue, - 'stepInterval' => new DateInterval($interval), + 'step' => new DateInterval($interval), )); $this->assertEquals($isValid, $validator->isValid($value)); From 91469fcde723d2f7d00703bf4ffdd83cd9f66fff Mon Sep 17 00:00:00 2001 From: Pieter Kokx Date: Sun, 1 Jul 2012 00:19:33 +0200 Subject: [PATCH 24/30] Fixed the unit tests for the new messages. --- test/AlnumTest.php | 4 ++-- test/DigitsTest.php | 6 +++--- test/MessageTest.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/AlnumTest.php b/test/AlnumTest.php index c3a78369e..27b119dfd 100644 --- a/test/AlnumTest.php +++ b/test/AlnumTest.php @@ -119,7 +119,7 @@ public function testEmptyStringValueResultsInProperValidationFailureMessages() $this->assertFalse($this->validator->isValid('')); $messages = $this->validator->getMessages(); $arrayExpected = array( - Alnum::STRING_EMPTY => '\'\' is an empty string' + Alnum::STRING_EMPTY => 'The input is an empty string' ); $this->assertThat($messages, $this->identicalTo($arrayExpected)); } @@ -132,7 +132,7 @@ public function testInvalidValueResultsInProperValidationFailureMessages() $this->assertFalse($this->validator->isValid('#')); $messages = $this->validator->getMessages(); $arrayExpected = array( - Alnum::NOT_ALNUM => '\'#\' contains characters which are non alphabetic and no digits' + Alnum::NOT_ALNUM => 'The input contains characters which are non alphabetic and no digits' ); $this->assertThat($messages, $this->identicalTo($arrayExpected)); } diff --git a/test/DigitsTest.php b/test/DigitsTest.php index 6bdf08d74..c153a32f5 100644 --- a/test/DigitsTest.php +++ b/test/DigitsTest.php @@ -84,7 +84,7 @@ public function testEmptyStringValueResultsInProperValidationFailureMessages() $this->assertFalse($this->validator->isValid('')); $messages = $this->validator->getMessages(); $arrayExpected = array( - Digits::STRING_EMPTY => '\'\' is an empty string' + Digits::STRING_EMPTY => 'The input is an empty string' ); $this->assertThat($messages, $this->identicalTo($arrayExpected)); } @@ -97,7 +97,7 @@ public function testInvalidValueResultsInProperValidationFailureMessages() $this->assertFalse($this->validator->isValid('#')); $messages = $this->validator->getMessages(); $arrayExpected = array( - Digits::NOT_DIGITS => '\'#\' must contain only digits' + Digits::NOT_DIGITS => 'The input must contain only digits' ); $this->assertThat($messages, $this->identicalTo($arrayExpected)); } @@ -116,4 +116,4 @@ public function testEqualsMessageTemplates() $this->assertAttributeEquals($validator->getOption('messageTemplates'), 'messageTemplates', $validator); } -} \ No newline at end of file +} diff --git a/test/MessageTest.php b/test/MessageTest.php index 6cce6d35d..dc0fb49b9 100644 --- a/test/MessageTest.php +++ b/test/MessageTest.php @@ -54,7 +54,7 @@ public function testSetMessage() $inputInvalid = 'abcdefghij'; $this->assertFalse($this->validator->isValid($inputInvalid)); $messages = $this->validator->getMessages(); - $this->assertEquals("'$inputInvalid' is more than 8 characters long", current($messages)); + $this->assertEquals("The input is more than 8 characters long", current($messages)); $this->validator->setMessage( 'Your value is too long', @@ -271,4 +271,4 @@ public function testEqualsMessageVariables() $this->assertAttributeEquals($validator->getOption('messageVariables'), 'messageVariables', $validator); } -} \ No newline at end of file +} From 79823e9ef900c3ef180d8895531ebd47d55ae2e1 Mon Sep 17 00:00:00 2001 From: Pieter Kokx Date: Sun, 1 Jul 2012 00:50:28 +0200 Subject: [PATCH 25/30] Added new validators. --- src/CreditCard.php | 2 +- src/DateStep.php | 4 ++-- src/Step.php | 2 +- src/Uri.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CreditCard.php b/src/CreditCard.php index e4d2a67c1..14a44dae2 100644 --- a/src/CreditCard.php +++ b/src/CreditCard.php @@ -69,7 +69,7 @@ class CreditCard extends AbstractValidator self::LENGTH => "The input contains an invalid amount of digits", self::PREFIX => "The input is not from an allowed institute", self::SERVICE => "The input seems to be an invalid creditcard number", - self::SERVICEFAILURE => "An exception has been raised while validating '%value%'", + self::SERVICEFAILURE => "An exception has been raised while validating the input.", ); /** diff --git a/src/DateStep.php b/src/DateStep.php index 5808df77c..596b7f47e 100644 --- a/src/DateStep.php +++ b/src/DateStep.php @@ -45,8 +45,8 @@ class DateStep extends AbstractValidator */ protected $messageTemplates = array( self::INVALID => "Invalid type given. String, integer, array or DateTime expected", - self::INVALID_DATE => "'%value%' does not appear to be a valid date", - self::NOT_STEP => "'%value%' is not a valid step." + self::INVALID_DATE => "The input does not appear to be a valid date", + self::NOT_STEP => "The input is not a valid step." ); /** diff --git a/src/Step.php b/src/Step.php index af7e706c6..e85f9bb00 100644 --- a/src/Step.php +++ b/src/Step.php @@ -38,7 +38,7 @@ class Step extends AbstractValidator */ protected $messageTemplates = array( self::INVALID => "Invalid value given. Scalar expected.", - self::NOT_STEP => "'%value%' is not a valid step." + self::NOT_STEP => "The input is not a valid step." ); /** diff --git a/src/Uri.php b/src/Uri.php index df63a7889..97a11445c 100644 --- a/src/Uri.php +++ b/src/Uri.php @@ -40,7 +40,7 @@ class Uri extends AbstractValidator */ protected $messageTemplates = array( self::INVALID => "Invalid type given. String expected", - self::NOT_URI => "'%value%' does not appear to be a valid Uri", + self::NOT_URI => "The input does not appear to be a valid Uri", ); /** From 5f04a7f9fffe910ce4ae454aee0735523dcd84bb Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 3 Jul 2012 08:41:08 -0500 Subject: [PATCH 26/30] [zendframework/zf2#1706] Move plugin registration - Removed Zend\I18n\Validator\ValidatorPluginManager - Added Iban and PostCode validators to Zend\Validator\ValidatorPluginManager --- src/ValidatorPluginManager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ValidatorPluginManager.php b/src/ValidatorPluginManager.php index 8edde26b2..48a9d5109 100644 --- a/src/ValidatorPluginManager.php +++ b/src/ValidatorPluginManager.php @@ -99,6 +99,7 @@ class ValidatorPluginManager extends AbstractPluginManager 'greaterthan' => 'Zend\Validator\GreaterThan', 'hex' => 'Zend\Validator\Hex', 'hostname' => 'Zend\Validator\Hostname', + 'iban' => 'Zend\I18n\Validator\Iban', 'identical' => 'Zend\Validator\Identical', 'inarray' => 'Zend\Validator\InArray', 'int' => 'Zend\Validator\Int', @@ -106,6 +107,7 @@ class ValidatorPluginManager extends AbstractPluginManager 'isbn' => 'Zend\Validator\Isbn', 'lessthan' => 'Zend\Validator\LessThan', 'notempty' => 'Zend\Validator\NotEmpty', + 'postcode' => 'Zend\I18n\Validator\PostCode', 'regex' => 'Zend\Validator\Regex', 'sitemapchangefreq' => 'Zend\Validator\Sitemap\Changefreq', 'sitemaplastmod' => 'Zend\Validator\Sitemap\Lastmod', From 18004be4b3acabb008e51943b7cc36935ec6f2d0 Mon Sep 17 00:00:00 2001 From: Denis Portnov Date: Wed, 4 Jul 2012 00:55:02 +0400 Subject: [PATCH 27/30] - remove Alnum dependency in Session - tests Alnum & Alpha validators --- src/Alnum.php | 127 -------------------------- src/Alpha.php | 132 --------------------------- src/ValidatorPluginManager.php | 4 +- test/AlnumTest.php | 162 --------------------------------- test/AlphaTest.php | 124 ------------------------- 5 files changed, 2 insertions(+), 547 deletions(-) delete mode 100644 src/Alnum.php delete mode 100644 src/Alpha.php delete mode 100644 test/AlnumTest.php delete mode 100644 test/AlphaTest.php diff --git a/src/Alnum.php b/src/Alnum.php deleted file mode 100644 index 0094f8a65..000000000 --- a/src/Alnum.php +++ /dev/null @@ -1,127 +0,0 @@ - "Invalid type given. String, integer or float expected", - self::NOT_ALNUM => "The input contains characters which are non alphabetic and no digits", - self::STRING_EMPTY => "The input is an empty string", - ); - - /** - * Options for this validator - * - * @var array - */ - protected $options = array( - 'allowWhiteSpace' => false, // Whether to allow white space characters; off by default - ); - - /** - * Sets default option values for this instance - * - * @param array|\Traversable $options - */ - public function __construct($options = array()) - { - parent::__construct($options); - } - - /** - * Returns the allowWhiteSpace option - * - * @return boolean - */ - public function getAllowWhiteSpace() - { - return $this->options['allowWhiteSpace']; - } - - /** - * Sets the allowWhiteSpace option - * - * @param boolean $allowWhiteSpace - * @return Alnum Provides a fluent interface - */ - public function setAllowWhiteSpace($allowWhiteSpace) - { - $this->options['allowWhiteSpace'] = (boolean) $allowWhiteSpace; - return $this; - } - - /** - * Returns true if and only if $value contains only alphabetic and digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value) && !is_int($value) && !is_float($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - if ('' === $value) { - $this->error(self::STRING_EMPTY); - return false; - } - - if (null === self::$filter) { - self::$filter = new AlnumFilter(); - } - - self::$filter->setAllowWhiteSpace($this->getAllowWhiteSpace()); - if ($value != self::$filter->filter($value)) { - $this->error(self::NOT_ALNUM); - return false; - } - - return true; - } -} diff --git a/src/Alpha.php b/src/Alpha.php deleted file mode 100644 index 9d3d80ad2..000000000 --- a/src/Alpha.php +++ /dev/null @@ -1,132 +0,0 @@ - "Invalid type given. String expected", - self::NOT_ALPHA => "The input contains non alphabetic characters", - self::STRING_EMPTY => "The input is an empty string" - ); - - /** - * Sets default option values for this instance - * - * @param boolean|array $allowWhiteSpace - */ - public function __construct($allowWhiteSpace = false) - { - parent::__construct(is_array($allowWhiteSpace) ? $allowWhiteSpace : null); - - if (is_scalar($allowWhiteSpace)) { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - } - } - - /** - * Returns the allowWhiteSpace option - * - * @return boolean - */ - public function getAllowWhiteSpace() - { - return $this->allowWhiteSpace; - } - - /** - * Sets the allowWhiteSpace option - * - * @param boolean $allowWhiteSpace - * @return \Zend\Filter\Alpha Provides a fluent interface - */ - public function setAllowWhiteSpace($allowWhiteSpace) - { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - return $this; - } - - /** - * Returns true if and only if $value contains only alphabetic characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - if (!is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - if ('' === $value) { - $this->error(self::STRING_EMPTY); - return false; - } - - if (null === self::$filter) { - self::$filter = new AlphaFilter(); - } - - self::$filter->setAllowWhiteSpace($this->allowWhiteSpace); - - if ($value !== self::$filter->filter($value)) { - $this->error(self::NOT_ALPHA); - return false; - } - - return true; - } - -} diff --git a/src/ValidatorPluginManager.php b/src/ValidatorPluginManager.php index 48a9d5109..600cd139d 100644 --- a/src/ValidatorPluginManager.php +++ b/src/ValidatorPluginManager.php @@ -36,8 +36,8 @@ class ValidatorPluginManager extends AbstractPluginManager * @var array */ protected $invokableClasses = array( - 'alnum' => 'Zend\Validator\Alnum', - 'alpha' => 'Zend\Validator\Alpha', + 'alnum' => 'Zend\I18n\Validator\Alnum', + 'alpha' => 'Zend\I18n\Validator\Alpha', 'barcodecode25interleaved' => 'Zend\Validator\Barcode\Code25interleaved', 'barcodecode25' => 'Zend\Validator\Barcode\Code25', 'barcodecode39ext' => 'Zend\Validator\Barcode\Code39ext', diff --git a/test/AlnumTest.php b/test/AlnumTest.php deleted file mode 100644 index 27b119dfd..000000000 --- a/test/AlnumTest.php +++ /dev/null @@ -1,162 +0,0 @@ -validator = new Alnum(); - } - - /** - * Ensures that the validator follows expected behavior for basic input values - * - * @return void - */ - public function testExpectedResultsWithBasicInputValues() - { - $valuesExpected = array( - 'abc123' => true, - 'abc 123' => false, - 'abcxyz' => true, - 'AZ@#4.3' => false, - 'aBc123' => true, - '' => false, - ' ' => false, - "\n" => false, - 'foobar1' => true - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals($result, $this->validator->isValid($input)); - } - } - - /** - * Ensures that getMessages() returns expected initial value - * - * @return void - */ - public function testMessagesEmptyInitially() - { - $this->assertEquals(array(), $this->validator->getMessages()); - } - - /** - * Ensures that the allowWhiteSpace option works as expected - * - * @return void - */ - public function testOptionToAllowWhiteSpaceWithBasicInputValues() - { - $this->validator->setAllowWhiteSpace(true); - - $valuesExpected = array( - 'abc123' => true, - 'abc 123' => true, - 'abcxyz' => true, - 'AZ@#4.3' => false, - 'aBc123' => true, - '' => false, - ' ' => true, - "\n" => true, - " \t " => true, - 'foobar1' => true - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals( - $result, - $this->validator->isValid($input), - "Expected '$input' to be considered " . ($result ? '' : 'in') . "valid" - ); - } - } - - /** - * @return void - */ - public function testEmptyStringValueResultsInProperValidationFailureMessages() - { - $this->assertFalse($this->validator->isValid('')); - $messages = $this->validator->getMessages(); - $arrayExpected = array( - Alnum::STRING_EMPTY => 'The input is an empty string' - ); - $this->assertThat($messages, $this->identicalTo($arrayExpected)); - } - - /** - * @return void - */ - public function testInvalidValueResultsInProperValidationFailureMessages() - { - $this->assertFalse($this->validator->isValid('#')); - $messages = $this->validator->getMessages(); - $arrayExpected = array( - Alnum::NOT_ALNUM => 'The input contains characters which are non alphabetic and no digits' - ); - $this->assertThat($messages, $this->identicalTo($arrayExpected)); - } - - /** - * @ZF-4352 - */ - public function testNonStringValidation() - { - $this->assertFalse($this->validator->isValid(array(1 => 1))); - } - - /** - * @ZF-7475 - */ - public function testIntegerValidation() - { - $this->assertTrue($this->validator->isValid(1)); - } - - public function testEqualsMessageTemplates() - { - $validator = $this->validator; - $this->assertAttributeEquals($validator->getOption('messageTemplates'), - 'messageTemplates', $validator); - } -} diff --git a/test/AlphaTest.php b/test/AlphaTest.php deleted file mode 100644 index 2bafbabae..000000000 --- a/test/AlphaTest.php +++ /dev/null @@ -1,124 +0,0 @@ -validator = new Alpha(); - } - - /** - * Ensures that the validator follows expected behavior - * - * @return void - */ - public function testBasic() - { - $valuesExpected = array( - 'abc123' => false, - 'abc 123' => false, - 'abcxyz' => true, - 'AZ@#4.3' => false, - 'aBc123' => false, - 'aBcDeF' => true, - '' => false, - ' ' => false, - "\n" => false - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals($result, $this->validator->isValid($input)); - } - } - - /** - * Ensures that getMessages() returns expected default value - * - * @return void - */ - public function testGetMessages() - { - $this->assertEquals(array(), $this->validator->getMessages()); - } - - /** - * Ensures that the allowWhiteSpace option works as expected - * - * @return void - */ - public function testAllowWhiteSpace() - { - $this->validator->setAllowWhiteSpace(true); - - $valuesExpected = array( - 'abc123' => false, - 'abc 123' => false, - 'abcxyz' => true, - 'AZ@#4.3' => false, - 'aBc123' => false, - 'aBcDeF' => true, - '' => false, - ' ' => true, - "\n" => true, - " \t " => true, - "a\tb c" => true - ); - foreach ($valuesExpected as $input => $result) { - $this->assertEquals( - $result, - $this->validator->isValid($input), - "Expected '$input' to be considered " . ($result ? '' : 'in') . "valid" - ); - } - } - - /** - * @ZF-4352 - */ - public function testNonStringValidation() - { - $this->assertFalse($this->validator->isValid(array(1 => 1))); - } - - public function testEqualsMessageTemplates() - { - $validator = $this->validator; - $this->assertAttributeEquals($validator->getOption('messageTemplates'), - 'messageTemplates', $validator); - } -} From 531785c43bdd32293ba367253559f04816f44e81 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 3 Jul 2012 17:42:51 -0500 Subject: [PATCH 28/30] [zendframework/zf2#1730] Fix bad test - Since Alpha switched namespaces, the import had to be updated in the StaticValidator tests --- test/StaticValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/StaticValidatorTest.php b/test/StaticValidatorTest.php index 9d17ece30..adb6da48d 100644 --- a/test/StaticValidatorTest.php +++ b/test/StaticValidatorTest.php @@ -22,7 +22,7 @@ namespace ZendTest\Validator; use Zend\Validator\AbstractValidator; -use Zend\Validator\Alpha; +use Zend\I18n\Validator\Alpha; use Zend\Validator\Between; use Zend\Validator\StaticValidator; use Zend\Validator\ValidatorPluginManager; From 62edf8756fcaccc55db399a84f350d9e0a0e958b Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 3 Jul 2012 17:35:46 -0500 Subject: [PATCH 29/30] [zen-66] Replaced Translator dep with I18n\Translator - Updated all Validators to use Zend\I18n\Translator in favor of Zend\Translator --- src/AbstractValidator.php | 60 ++++++++++++++---------------- test/AbstractTest.php | 55 +++++++++++++++------------ test/EmailAddressTest.php | 24 ++++++++---- test/HostnameTest.php | 9 ++++- test/StaticValidatorTest.php | 31 ++++++++------- test/TestAsset/ArrayTranslator.php | 16 ++++++++ test/ValidatorChainTest.php | 9 ++--- 7 files changed, 118 insertions(+), 86 deletions(-) create mode 100644 test/TestAsset/ArrayTranslator.php diff --git a/src/AbstractValidator.php b/src/AbstractValidator.php index 4ef2f2b52..674d3859e 100644 --- a/src/AbstractValidator.php +++ b/src/AbstractValidator.php @@ -21,9 +21,9 @@ namespace Zend\Validator; use Traversable; +use Zend\I18n\Translator\Translator; use Zend\Registry; use Zend\Stdlib\ArrayUtils; -use Zend\Translator; use Zend\Validator\Exception\InvalidArgumentException; /** @@ -43,7 +43,7 @@ abstract class AbstractValidator implements ValidatorInterface /** * Default translation object for all validate objects - * @var \Zend\Translator\Adapter\AbstractAdapter + * @var Translator */ protected static $defaultTranslator; @@ -58,7 +58,7 @@ abstract class AbstractValidator implements ValidatorInterface 'messages' => array(), // Array of validation failure messages 'messageTemplates' => array(), // Array of validation failure message templates 'messageVariables' => array(), // Array of additional variables available for validation failure messages - 'translator' => null, // Translation object to used -> \Zend\Translator\Translator + 'translator' => null, // Translation object to used -> Zend\I18n\Translator\Translator 'translatorDisabled' => false, // Is translation disabled? 'valueObscured' => false, // Flag indicating whether or not value should be obfuscated in error messages ); @@ -298,13 +298,7 @@ protected function createMessage($messageKey, $value) $message = $this->abstractOptions['messageTemplates'][$messageKey]; - if (null !== ($translator = $this->getTranslator())) { - if ($translator->isTranslated($messageKey)) { - $message = $translator->translate($messageKey); - } else { - $message = $translator->translate($message); - } - } + $message = $this->translateMessage($messageKey, $message); if (is_object($value) && !in_array('__toString', get_class_methods($value)) @@ -408,27 +402,20 @@ public function isValueObscured() /** * Set translation object * - * @param \Zend\Translator\Translator|\Zend\Translator\Adapter\AbstractAdapter|null $translator + * @param Translator|null $translator * @return AbstractValidator * @throws Exception\InvalidArgumentException */ - public function setTranslator($translator = null) + public function setTranslator(Translator $translator = null) { - if ((null === $translator) || ($translator instanceof Translator\Adapter\AbstractAdapter)) { - $this->abstractOptions['translator'] = $translator; - } elseif ($translator instanceof Translator\Translator) { - $this->abstractOptions['translator'] = $translator->getAdapter(); - } else { - throw new InvalidArgumentException('Invalid translator specified'); - } - + $this->abstractOptions['translator'] = $translator; return $this; } /** * Return translation object * - * @return \Zend\Translator\Adapter\AbstractAdapter|null + * @return Translator|null */ public function getTranslator() { @@ -456,25 +443,19 @@ public function hasTranslator() /** * Set default translation object for all validate objects * - * @param \Zend\Translator\Translator|\Zend\Translator\Adapter\AbstractAdapter|null $translator + * @param Translator|null $translator * @return void * @throws Exception\InvalidArgumentException */ - public static function setDefaultTranslator($translator = null) + public static function setDefaultTranslator(Translator $translator = null) { - if ((null === $translator) || ($translator instanceof Translator\Adapter\AbstractAdapter)) { - self::$defaultTranslator = $translator; - } elseif ($translator instanceof Translator\Translator) { - self::$defaultTranslator = $translator->getAdapter(); - } else { - throw new InvalidArgumentException('Invalid translator specified'); - } + self::$defaultTranslator = $translator; } /** * Get default translation object for all validate objects * - * @return \Zend\Translator\Adapter\AbstractAdapter|null + * @return Translator|null */ public static function getDefaultTranslator() { @@ -488,7 +469,7 @@ public static function getDefaultTranslator() */ public static function hasDefaultTranslator() { - return (bool)self::$defaultTranslator; + return (bool) self::$defaultTranslator; } /** @@ -532,4 +513,19 @@ public static function setMessageLength($length = -1) { self::$messageLength = $length; } + + protected function translateMessage($messageKey, $message) + { + $translator = $this->getTranslator(); + if (!$translator) { + return $message; + } + + $translated = $translator->translate($messageKey); + if ($translated !== $messageKey) { + return $translated; + } + + return $translator->translate($message); + } } diff --git a/test/AbstractTest.php b/test/AbstractTest.php index 8c4e3ba2c..2362c5059 100644 --- a/test/AbstractTest.php +++ b/test/AbstractTest.php @@ -21,7 +21,8 @@ namespace ZendTest\Validator; -use Zend\Translator; +use Locale; +use Zend\I18n\Translator\Translator; use Zend\Validator\AbstractValidator; /** @@ -58,10 +59,10 @@ public function testCanSetTranslator() { $this->testTranslatorNullByDefault(); set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator('ArrayAdapter', array(), 'en'); + $translator = new Translator(); restore_error_handler(); $this->validator->setTranslator($translator); - $this->assertSame($translator->getAdapter(), $this->validator->getTranslator()); + $this->assertSame($translator, $this->validator->getTranslator()); } public function testCanSetTranslatorToNull() @@ -78,35 +79,41 @@ public function testGlobalDefaultTranslatorNullByDefault() $this->assertNull(AbstractValidator::getDefaultTranslator()); } - - public function testErrorMessagesAreTranslatedWhenTranslatorPresent() { - $translator = new Translator\Translator( - 'ArrayAdapter', - array('fooMessage' => 'This is the translated message for %value%'), - 'en' + Locale::setDefault('en_US'); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = array( + 'fooMessage' => 'This is the translated message for %value%', ); + $translator = new Translator(); + $translator->getPluginManager()->setService('default', $loader); + $translator->addTranslationFile('default', null); + $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid('bar')); $messages = $this->validator->getMessages(); $this->assertTrue(array_key_exists('fooMessage', $messages)); - $this->assertContains('bar', $messages['fooMessage']); + $this->assertContains('bar', $messages['fooMessage'], var_export($messages, 1)); $this->assertContains('This is the translated message for ', $messages['fooMessage']); } public function testCanTranslateMessagesInsteadOfKeys() { - $translator = new Translator\Translator( - 'ArrayAdapter', - array('%value% was passed' => 'This is the translated message for %value%'), - 'en' + Locale::setDefault('en_US'); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = array( + '%value% was passed' => 'This is the translated message for %value%', ); + $translator = new Translator(); + $translator->getPluginManager()->setService('default', $loader); + $translator->addTranslationFile('default', null); + $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid('bar')); $messages = $this->validator->getMessages(); $this->assertTrue(array_key_exists('fooMessage', $messages)); - $this->assertContains('bar', $messages['fooMessage']); + $this->assertContains('bar', $messages['fooMessage'], var_export($messages, 1)); $this->assertContains('This is the translated message for ', $messages['fooMessage']); } @@ -148,21 +155,21 @@ public function testDoesNotFailOnObjectInput() public function testTranslatorEnabledPerDefault() { set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator('ArrayAdapter', array(), 'en'); - restore_error_handler(); + $translator = new Translator(); $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isTranslatorDisabled()); } public function testCanDisableTranslator() { - set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator( - 'ArrayAdapter', - array('fooMessage' => 'This is the translated message for %value%'), - 'en' + Locale::setDefault('en_US'); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = array( + '%value% was passed' => 'This is the translated message for %value%', ); - restore_error_handler(); + $translator = new Translator(); + $translator->getPluginManager()->setService('default', $loader); + $translator->addTranslationFile('default', null); $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid('bar')); @@ -214,4 +221,4 @@ public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $e { $this->errorOccurred = true; } -} \ No newline at end of file +} diff --git a/test/EmailAddressTest.php b/test/EmailAddressTest.php index 5e1621186..3eeecdfa2 100644 --- a/test/EmailAddressTest.php +++ b/test/EmailAddressTest.php @@ -21,6 +21,8 @@ namespace ZendTest\Validator; +use Locale; +use Zend\I18n\Translator\Translator; use Zend\Validator\EmailAddress; use Zend\Validator\Hostname; @@ -365,16 +367,22 @@ public function testHostnameValidatorMessagesShouldBeTranslated() { $hostnameValidator = new Hostname(); $translations = array( - 'hostnameIpAddressNotAllowed' => 'hostnameIpAddressNotAllowed translation', - 'hostnameUnknownTld' => 'hostnameUnknownTld translation', - 'hostnameDashCharacter' => 'hostnameDashCharacter translation', + 'hostnameIpAddressNotAllowed' => 'hostnameIpAddressNotAllowed translation', + 'hostnameUnknownTld' => 'hostnameUnknownTld translation', + 'hostnameDashCharacter' => 'hostnameDashCharacter translation', 'hostnameInvalidHostnameSchema' => 'hostnameInvalidHostnameSchema translation', - 'hostnameUndecipherableTld' => 'hostnameUndecipherableTld translation', - 'hostnameInvalidHostname' => 'hostnameInvalidHostname translation', - 'hostnameInvalidLocalName' => 'hostnameInvalidLocalName translation', - 'hostnameLocalNameNotAllowed' => 'hostnameLocalNameNotAllowed translation', + 'hostnameUndecipherableTld' => 'hostnameUndecipherableTld translation', + 'hostnameInvalidHostname' => 'hostnameInvalidHostname translation', + 'hostnameInvalidLocalName' => 'hostnameInvalidLocalName translation', + 'hostnameLocalNameNotAllowed' => 'hostnameLocalNameNotAllowed translation', ); - $translator = new \Zend\Translator\Translator('ArrayAdapter', $translations); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = $translations; + $translator = new Translator(); + Locale::setDefault('en_US'); + $translator->getPluginManager()->setService('test', $loader); + $translator->addTranslationFile('test', null); + $this->validator->setTranslator($translator)->setHostnameValidator($hostnameValidator); $this->validator->isValid('_XX.!!3xx@0.239,512.777'); diff --git a/test/HostnameTest.php b/test/HostnameTest.php index dcee66fb5..ccffccfaf 100644 --- a/test/HostnameTest.php +++ b/test/HostnameTest.php @@ -21,6 +21,8 @@ namespace ZendTest\Validator; +use Locale; +use Zend\I18n\Translator\Translator; use Zend\Validator\Hostname; /** @@ -276,7 +278,12 @@ public function testValidatorMessagesShouldBeTranslated() $translations = array( 'hostnameInvalidLocalName' => 'this is the IP error message', ); - $translator = new \Zend\Translator\Translator('ArrayAdapter', $translations); + Locale::setDefault('en_US'); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = $translations; + $translator = new Translator(); + $translator->getPluginManager()->setService('default', $loader); + $translator->addTranslationFile('default', null); $this->validator->setTranslator($translator); $this->validator->isValid('0.239,512.777'); diff --git a/test/StaticValidatorTest.php b/test/StaticValidatorTest.php index adb6da48d..cd1d8ae6d 100644 --- a/test/StaticValidatorTest.php +++ b/test/StaticValidatorTest.php @@ -21,12 +21,13 @@ namespace ZendTest\Validator; +use Locale; +use Zend\I18n\Translator; use Zend\Validator\AbstractValidator; use Zend\I18n\Validator\Alpha; use Zend\Validator\Between; use Zend\Validator\StaticValidator; use Zend\Validator\ValidatorPluginManager; -use Zend\Translator; /** * @category Zend @@ -83,11 +84,9 @@ public function errorHandlerIgnore($errno, $errstr, $errfile, $errline, array $e public function testCanSetGlobalDefaultTranslator() { - set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator('ArrayAdapter', array(), 'en'); - restore_error_handler(); + $translator = new Translator\Translator(); AbstractValidator::setDefaultTranslator($translator); - $this->assertSame($translator->getAdapter(), AbstractValidator::getDefaultTranslator()); + $this->assertSame($translator, AbstractValidator::getDefaultTranslator()); } public function testGlobalDefaultTranslatorUsedWhenNoLocalTranslatorSet() @@ -99,9 +98,7 @@ public function testGlobalDefaultTranslatorUsedWhenNoLocalTranslatorSet() public function testLocalTranslatorPreferredOverGlobalTranslator() { $this->testCanSetGlobalDefaultTranslator(); - set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator('ArrayAdapter', array(), 'en'); - restore_error_handler(); + $translator = new Translator\Translator(); $this->validator->setTranslator($translator); $this->assertNotSame(AbstractValidator::getDefaultTranslator(), $this->validator->getTranslator()); } @@ -112,11 +109,15 @@ public function testMaximumErrorMessageLength() AbstractValidator::setMessageLength(10); $this->assertEquals(10, AbstractValidator::getMessageLength()); - $translator = new Translator\Translator( - 'ArrayAdapter', - array(Alpha::INVALID => 'This is the translated message for %value%'), - 'en' + Locale::setDefault('en_US'); + $loader = new TestAsset\ArrayTranslator(); + $loader->translations = array( + Alpha::INVALID => 'This is the translated message for %value%', ); + $translator = new Translator\Translator(); + $translator->getPluginManager()->setService('default', $loader); + $translator->addTranslationFile('default', null); + $this->validator->setTranslator($translator); $this->assertFalse($this->validator->isValid(123)); $messages = $this->validator->getMessages(); @@ -137,11 +138,9 @@ public function testSetGetMessageLengthLimitation() public function testSetGetDefaultTranslator() { - set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new Translator\Translator('ArrayAdapter', array(), 'en'); - restore_error_handler(); + $translator = new Translator\Translator(); AbstractValidator::setDefaultTranslator($translator); - $this->assertSame($translator->getAdapter(), AbstractValidator::getDefaultTranslator()); + $this->assertSame($translator, AbstractValidator::getDefaultTranslator()); } /* plugin loading */ diff --git a/test/TestAsset/ArrayTranslator.php b/test/TestAsset/ArrayTranslator.php new file mode 100644 index 000000000..d1a93c40a --- /dev/null +++ b/test/TestAsset/ArrayTranslator.php @@ -0,0 +1,16 @@ +translations); + return $textDomain; + } +} diff --git a/test/ValidatorChainTest.php b/test/ValidatorChainTest.php index b2c64ac16..a081317a7 100644 --- a/test/ValidatorChainTest.php +++ b/test/ValidatorChainTest.php @@ -21,6 +21,7 @@ namespace ZendTest\Validator; +use Zend\I18n\Translator\Translator; use Zend\Validator\AbstractValidator; use Zend\Validator\Between; use Zend\Validator\StaticValidator; @@ -135,11 +136,9 @@ public function testSetGetMessageLengthLimitation() public function testSetGetDefaultTranslator() { - set_error_handler(array($this, 'errorHandlerIgnore')); - $translator = new \Zend\Translator\Translator('ArrayAdapter', array(), 'en'); - restore_error_handler(); + $translator = new Translator(); AbstractValidator::setDefaultTranslator($translator); - $this->assertSame($translator->getAdapter(), AbstractValidator::getDefaultTranslator()); + $this->assertSame($translator, AbstractValidator::getDefaultTranslator()); } public function testAllowsPrependingValidators() @@ -216,4 +215,4 @@ public function getValidatorFalse() ->will($this->returnValue(array('error' => 'validation failed'))); return $validator; } -} \ No newline at end of file +} From 22716b3d5c6e58945161fbc670f30de8fd681e09 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 3 Jul 2012 17:45:48 -0500 Subject: [PATCH 30/30] [zen-66] Remove Locale from tests - Not needed, so removed --- test/AbstractTest.php | 4 ---- test/EmailAddressTest.php | 2 -- test/HostnameTest.php | 2 -- test/StaticValidatorTest.php | 2 -- 4 files changed, 10 deletions(-) diff --git a/test/AbstractTest.php b/test/AbstractTest.php index 2362c5059..eb6485ffb 100644 --- a/test/AbstractTest.php +++ b/test/AbstractTest.php @@ -21,7 +21,6 @@ namespace ZendTest\Validator; -use Locale; use Zend\I18n\Translator\Translator; use Zend\Validator\AbstractValidator; @@ -81,7 +80,6 @@ public function testGlobalDefaultTranslatorNullByDefault() public function testErrorMessagesAreTranslatedWhenTranslatorPresent() { - Locale::setDefault('en_US'); $loader = new TestAsset\ArrayTranslator(); $loader->translations = array( 'fooMessage' => 'This is the translated message for %value%', @@ -100,7 +98,6 @@ public function testErrorMessagesAreTranslatedWhenTranslatorPresent() public function testCanTranslateMessagesInsteadOfKeys() { - Locale::setDefault('en_US'); $loader = new TestAsset\ArrayTranslator(); $loader->translations = array( '%value% was passed' => 'This is the translated message for %value%', @@ -162,7 +159,6 @@ public function testTranslatorEnabledPerDefault() public function testCanDisableTranslator() { - Locale::setDefault('en_US'); $loader = new TestAsset\ArrayTranslator(); $loader->translations = array( '%value% was passed' => 'This is the translated message for %value%', diff --git a/test/EmailAddressTest.php b/test/EmailAddressTest.php index 3eeecdfa2..d472dbd85 100644 --- a/test/EmailAddressTest.php +++ b/test/EmailAddressTest.php @@ -21,7 +21,6 @@ namespace ZendTest\Validator; -use Locale; use Zend\I18n\Translator\Translator; use Zend\Validator\EmailAddress; use Zend\Validator\Hostname; @@ -379,7 +378,6 @@ public function testHostnameValidatorMessagesShouldBeTranslated() $loader = new TestAsset\ArrayTranslator(); $loader->translations = $translations; $translator = new Translator(); - Locale::setDefault('en_US'); $translator->getPluginManager()->setService('test', $loader); $translator->addTranslationFile('test', null); diff --git a/test/HostnameTest.php b/test/HostnameTest.php index ccffccfaf..ad262cf40 100644 --- a/test/HostnameTest.php +++ b/test/HostnameTest.php @@ -21,7 +21,6 @@ namespace ZendTest\Validator; -use Locale; use Zend\I18n\Translator\Translator; use Zend\Validator\Hostname; @@ -278,7 +277,6 @@ public function testValidatorMessagesShouldBeTranslated() $translations = array( 'hostnameInvalidLocalName' => 'this is the IP error message', ); - Locale::setDefault('en_US'); $loader = new TestAsset\ArrayTranslator(); $loader->translations = $translations; $translator = new Translator(); diff --git a/test/StaticValidatorTest.php b/test/StaticValidatorTest.php index cd1d8ae6d..9175eb0e4 100644 --- a/test/StaticValidatorTest.php +++ b/test/StaticValidatorTest.php @@ -21,7 +21,6 @@ namespace ZendTest\Validator; -use Locale; use Zend\I18n\Translator; use Zend\Validator\AbstractValidator; use Zend\I18n\Validator\Alpha; @@ -109,7 +108,6 @@ public function testMaximumErrorMessageLength() AbstractValidator::setMessageLength(10); $this->assertEquals(10, AbstractValidator::getMessageLength()); - Locale::setDefault('en_US'); $loader = new TestAsset\ArrayTranslator(); $loader->translations = array( Alpha::INVALID => 'This is the translated message for %value%',