Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added a new validator to check if input is instance of certain class #2414

Closed
wants to merge 6 commits into from

3 participants

@jvandemo

Useful if you need to check if a value is an instance of a certain class.

Also useful as an annotation in your entity classes if you need to make sure that a certain class property is an instance of a specific class.

Example:

$validator = new \Zend\Validator\IsInstanceOf(
                array(
                    'className' => '\DateTime'
                ));

$validator->isValid(new \DateTime()); // true
$validator->isValid(new AnyObjectThatIsNotDateTime()); // false
$validator->isValid(''); // false
$validator->isValid(null); // false

Example as annotation:

/*
 * @Annotation\Validator({"name":"IsInstanceOf", "options":{"className":"\DateTime"}})
 */

Change-Id: I6365cf9a6652ca42a1f6897002e5abe455ed4f44

Jurgen Van de Moere Add new validator to check if input is instance of a certain class
Change-Id: I6365cf9a6652ca42a1f6897002e5abe455ed4f44
986df50
@bakura10

This is a good idea. I provided some CS feedbacks in the code.

However, I think you should have an abstract AbstractInstanceOf and two inherited classes InstanceOf (instead of IsInstanceOf, it sounds strange for a class to have a name beginning by Is, plus it will provide some similarity to instanceof operator in PHP) / NotInstanceOf

library/Zend/Validator/IsInstanceOf.php
((4 lines not shown))
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Validator
+ */
+
+namespace Zend\Validator;
+
+use Traversable;
+use Zend\Stdlib\ArrayUtils;
+use Zend\Validator\AbstractValidator;
+
+class IsInstanceOf extends AbstractValidator
+{
+

Remove empty line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
library/Zend/Validator/IsInstanceOf.php
((38 lines not shown))
+ );
+
+ /**
+ * Class name
+ *
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * Sets validator options
+ *
+ * @param array|Traversable $options
+ * @throws Exception\InvalidArgumentException
+ */
+ public function __construct($options = null)

Please check if you cannot reuse the setOptions function of the base class here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Jurgen Van de Moere - Removed empty line
- Removed call to setClassName() in constructor so it uses the parent
constructor (and setOptions()) to set the options

Change-Id: I0720d0543b0a6918b7e8a0817d353aff668f5517
f3ee95e
@jvandemo

You're right, I removed the empty line and changed the constructor to use the parent constructor (and thus the setOptions()).

@jvandemo

@bakura10 I agree that InstanceOf would be a better name for the class, but it gets rejected as class name because it is a reserved word...

Jurgen Van de Moere Fix trailing spaces
Change-Id: I5e6aa688d783761c23d179b154a7fff8ef6785d4
7864834
@weierophinney

We've used "Is as a prefix before; I'm fine with that.

library/Zend/Validator/IsInstanceOf.php
((46 lines not shown))
+ /**
+ * Sets validator options
+ *
+ * @param array|Traversable $options
+ * @throws Exception\InvalidArgumentException
+ */
+ public function __construct($options = null)
+ {
+ if ($options instanceof Traversable) {
+ $options = ArrayUtils::iteratorToArray($options);
+ }
+ if (!is_array($options)) {
+ $options = func_get_args();
+
+ $tmpOptions = array();
+ $tmpOptions['classname'] = array_shift($options);
@weierophinney Owner

Shouldn't this be "className"?

Actually, to be quite clear: use "class_name" as the option key. This is safer from a validation standpoint.

Thanks for noticing, I corrected it.

I didn't change it to class_name, because the setClassName function is automatically resolved and called by setOptions when using className as option name.

If you insists on renaming it to class_name, let me know so I can refactor it.

Thanks !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
library/Zend/Validator/IsInstanceOf.php
((88 lines not shown))
+ */
+ public function setClassName($className)
+ {
+ $this->className = $className;
+ return $this;
+ }
+
+ /**
+ * Returns true if $value is instance of $this->className
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ if($value instanceof $this->className) {
@weierophinney Owner

Add a space between the "if" and opening paren.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney

Needs tests, and also needs an entry in the ValidatorPluginManager. Otherwise, looking good.

@jvandemo

@weierophinney Thanks for the feedback, I'll implement your suggestions and let you know when finished. Thanks !

Jurgen Van d... added some commits
Jurgen Van de Moere Validor suggestions implemented and entries added to ValidatorLoader
Change-Id: Idd449f4a6ac538050e4ca2d114504668ebe7faaa
5ff1474
Jurgen Van de Moere Added PHPUnit test IsInstanceOfTest for Zend\Validator\IsInstanceOf
Change-Id: I11ad45466dc91e481e03f74936ca859fba44b70b
09bf94e
Jurgen Van de Moere Corrected reference in comment
Change-Id: Ib5e2b582481dd943941a5277630c6b0d39dd7191
62e57ee
@jvandemo

@weierophinney All requested changes/features were implemented. Let me know if you need something else. Thanks !!

@weierophinney weierophinney commented on the diff
library/Zend/Validator/IsInstanceOf.php
((41 lines not shown))
+ * Class name
+ *
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * Sets validator options
+ *
+ * @param array|Traversable $options
+ * @throws Zend\Validator\Exception\InvalidArgumentException
+ */
+ public function __construct ($options = null)
+ {
+ if ($options instanceof Traversable) {
+ $options = ArrayUtils::iteratorToArray($options);
@weierophinney Owner

Since the configuration array is flat, you can use simply iterator_to_array() here, and avoid the dependency. (I'll likely make this change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney commented on the diff
library/Zend/Validator/ValidatorLoader.php
@@ -224,6 +224,9 @@ class ValidatorLoader extends PluginClassLoader
'int' => 'Zend\Validator\Int',
'ip' => 'Zend\Validator\Ip',
'isbn' => 'Zend\Validator\Isbn',
+ 'isinstanceof' => 'Zend\Validator\IsInstanceOf',
+ 'is_instanceof' => 'Zend\Validator\IsInstanceOf',
+ 'is_instance_of' => 'Zend\Validator\IsInstanceOf',
@weierophinney Owner

During canonicalization of a name, spaces, underscores, slashes, etc. are stripped -- which means that lines 228 and 229 are not necessary. (I'll likely make that change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney commented on the diff
tests/Zend/Validator/IsInstanceOfTest.php
((36 lines not shown))
+ * @subpackage UnitTests
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @group Zend_Validator
+ */
+class IsInstanceOfTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * Ensures that the validator follows expected behavior
+ *
+ * @return void
+ */
+ public function testBasic ()
+ {
+ $validator = new Validator\IsInstanceOf('\DateTime');
@weierophinney Owner

Since class names in strings are always considered fully qualified, the leading \ is not necessary. (I'll likely make that change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney referenced this pull request from a commit
@weierophinney weierophinney [#2414] CS review
- Removed unnecessary imports
- Added required imports (in testing)
- Removed extraneous whitespace
- Removed unnecessary dependency (ArrayUtils)
0107f11
@weierophinney

Will release with 2.1.0.

@jvandemo

Awesome, let met know if you need any further help.

Thanks for the quick follow up and hints !!!

@weierophinney weierophinney referenced this pull request from a commit
@weierophinney weierophinney [#2414] move test to correct directory
- was in tests/Zend/ instead of tests/ZendTest/
ceb20c5
@ghost Unknown referenced this pull request from a commit
@weierophinney weierophinney [#2414] CS review
- Removed unnecessary imports
- Added required imports (in testing)
- Removed extraneous whitespace
- Removed unnecessary dependency (ArrayUtils)
ac7590a
@ghost Unknown referenced this pull request from a commit
@weierophinney weierophinney [#2414] move test to correct directory
- was in tests/Zend/ instead of tests/ZendTest/
846164e
@weierophinney weierophinney referenced this pull request from a commit in zendframework/zend-validator
@weierophinney weierophinney [zendframework/zf2#2414] Added IsInstanceOf to ValidatorPluginManager 63efbf9
@weierophinney weierophinney referenced this pull request from a commit in zendframework/zend-validator
@weierophinney weierophinney [zendframework/zf2#2414] CS review
- Removed unnecessary imports
- Added required imports (in testing)
- Removed extraneous whitespace
- Removed unnecessary dependency (ArrayUtils)
893ce23
@weierophinney weierophinney referenced this pull request from a commit in zendframework/zend-validator
@weierophinney weierophinney Merge branch 'feature/validator-instanceof' into develop 56417a5
@weierophinney weierophinney referenced this pull request from a commit in zendframework/zend-validator
@weierophinney weierophinney [zendframework/zf2#2414] move test to correct directory
- was in tests/Zend/ instead of tests/ZendTest/
49fd3be
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 25, 2012
  1. Add new validator to check if input is instance of a certain class

    Jurgen Van de Moere authored
    Change-Id: I6365cf9a6652ca42a1f6897002e5abe455ed4f44
  2. - Removed empty line

    Jurgen Van de Moere authored
    - Removed call to setClassName() in constructor so it uses the parent
    constructor (and setOptions()) to set the options
    
    Change-Id: I0720d0543b0a6918b7e8a0817d353aff668f5517
  3. Fix trailing spaces

    Jurgen Van de Moere authored
    Change-Id: I5e6aa688d783761c23d179b154a7fff8ef6785d4
  4. Validor suggestions implemented and entries added to ValidatorLoader

    Jurgen Van de Moere authored
    Change-Id: Idd449f4a6ac538050e4ca2d114504668ebe7faaa
  5. Added PHPUnit test IsInstanceOfTest for Zend\Validator\IsInstanceOf

    Jurgen Van de Moere authored
    Change-Id: I11ad45466dc91e481e03f74936ca859fba44b70b
  6. Corrected reference in comment

    Jurgen Van de Moere authored
    Change-Id: Ib5e2b582481dd943941a5277630c6b0d39dd7191
This page is out of date. Refresh to see the latest.
View
112 library/Zend/Validator/IsInstanceOf.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Validator
+ */
+namespace Zend\Validator;
+
+use Traversable;
+use Zend\Stdlib\ArrayUtils;
+use Zend\Validator\AbstractValidator;
+use Zend\Validator\Exception\InvalidArgumentException;
+
+class IsInstanceOf extends AbstractValidator
+{
+
+ const NOT_INSTANCE_OF = 'notInstanceOf';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $messageTemplates = array(
+ self::NOT_INSTANCE_OF => "The input is not an instance of '%className%'"
+ );
+
+ /**
+ * Additional variables available for validation failure messages
+ *
+ * @var array
+ */
+ protected $messageVariables = array(
+ 'className' => 'className'
+ );
+
+ /**
+ * Class name
+ *
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * Sets validator options
+ *
+ * @param array|Traversable $options
+ * @throws Zend\Validator\Exception\InvalidArgumentException
+ */
+ public function __construct ($options = null)
+ {
+ if ($options instanceof Traversable) {
+ $options = ArrayUtils::iteratorToArray($options);
@weierophinney Owner

Since the configuration array is flat, you can use simply iterator_to_array() here, and avoid the dependency. (I'll likely make this change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ // If argument is not an array, consider first argument as class name
+ if (! is_array($options)) {
+ $options = func_get_args();
+
+ $tmpOptions = array();
+ $tmpOptions['className'] = array_shift($options);
+
+ $options = $tmpOptions;
+ }
+
+ if (! array_key_exists('className', $options)) {
+ throw new InvalidArgumentException("Missing option 'className'");
+ }
+
+ parent::__construct($options);
+ }
+
+ /**
+ * Get class name
+ *
+ * @return string
+ */
+ public function getClassName ()
+ {
+ return $this->className;
+ }
+
+ /**
+ * Set class name
+ *
+ * @param string $className
+ * @return self
+ */
+ public function setClassName ($className)
+ {
+ $this->className = $className;
+ return $this;
+ }
+
+ /**
+ * Returns true if $value is instance of $this->className
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid ($value)
+ {
+ if ($value instanceof $this->className) {
+ return true;
+ }
+ $this->error(self::NOT_INSTANCE_OF);
+ return false;
+ }
+}
View
5 library/Zend/Validator/ValidatorLoader.php
@@ -33,7 +33,7 @@
class ValidatorLoader extends PluginClassLoader
{
/**
- * @var array Pre-aliased filter
+ * @var array Pre-aliased filter
*/
protected $plugins = array(
'alnum' => 'Zend\Validator\Alnum',
@@ -224,6 +224,9 @@ class ValidatorLoader extends PluginClassLoader
'int' => 'Zend\Validator\Int',
'ip' => 'Zend\Validator\Ip',
'isbn' => 'Zend\Validator\Isbn',
+ 'isinstanceof' => 'Zend\Validator\IsInstanceOf',
+ 'is_instanceof' => 'Zend\Validator\IsInstanceOf',
+ 'is_instance_of' => 'Zend\Validator\IsInstanceOf',
@weierophinney Owner

During canonicalization of a name, spaces, underscores, slashes, etc. are stripped -- which means that lines 228 and 229 are not necessary. (I'll likely make that change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
'less_than' => 'Zend\Validator\LessThan',
'lessthan' => 'Zend\Validator\LessThan',
'not_empty' => 'Zend\Validator\NotEmpty',
View
121 tests/Zend/Validator/IsInstanceOfTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validator
+ * @subpackage UnitTests
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace ZendTest\Validator;
+
+use Zend\Validator, ReflectionClass;
+
+/**
+ * Test helper
+ */
+
+/**
+ * @see Zend_Validator_IsInstanceOf
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Validator
+ * @subpackage UnitTests
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @group Zend_Validator
+ */
+class IsInstanceOfTest extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * Ensures that the validator follows expected behavior
+ *
+ * @return void
+ */
+ public function testBasic ()
+ {
+ $validator = new Validator\IsInstanceOf('\DateTime');
@weierophinney Owner

Since class names in strings are always considered fully qualified, the leading \ is not necessary. (I'll likely make that change during merge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ $this->assertTrue($validator->isValid(new \DateTime())); // True
+ $this->assertFalse($validator->isValid(null)); // False
+ $this->assertFalse($validator->isValid($this)); // False
+
+ $validator = new Validator\IsInstanceOf('\Exception');
+
+ $this->assertTrue($validator->isValid(new \Exception())); // True
+ $this->assertFalse($validator->isValid(null)); // False
+ $this->assertFalse($validator->isValid($this)); // False
+
+ $validator = new Validator\IsInstanceOf('\PHPUnit_Framework_TestCase');
+
+ $this->assertTrue($validator->isValid($this)); // True
+ }
+
+ /**
+ * Ensures that getMessages() returns expected default value
+ *
+ * @return void
+ */
+ public function testGetMessages ()
+ {
+ $validator = new Validator\IsInstanceOf('\DateTime');
+ $this->assertEquals(array(), $validator->getMessages());
+ }
+
+ /**
+ * Ensures that getClassName() returns expected value
+ *
+ * @return void
+ */
+ public function testGetClassName ()
+ {
+ $validator = new Validator\IsInstanceOf('\DateTime');
+ $this->assertEquals('\DateTime', $validator->getClassName());
+ }
+
+ public function testEqualsMessageTemplates ()
+ {
+ $validator = new Validator\IsInstanceOf('\DateTime');
+ $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\IsInstanceOf('\DateTime');
+ $reflection = new ReflectionClass($validator);
+
+ if (! $reflection->hasProperty('_messageVariables')) {
+ return;
+ }
+
+ $property = $reflection->getProperty('_messageVariables');
+ $property->setAccessible(true);
+
+ $this->assertEquals($property->getValue($validator),
+ $validator->getOption('messageVariables'));
+ }
+}
Something went wrong with that request. Please try again.