Permalink
Browse files

Added filter possibility

  • Loading branch information...
iwalz committed Jan 6, 2013
1 parent c21f78c commit 0e9664a92ab97eff1f37f0aa7ec46ac4d230787c
@@ -10,7 +10,11 @@
namespace Zend\Stdlib\Hydrator;
-use Zend\Stdlib\Exception;
+use Zend\Stdlib\Exception,
+ Zend\Stdlib\Hydrator\Filter\FilterComposite,
+ Zend\Stdlib\Hydrator\Filter\IsFilter,
+ Zend\Stdlib\Hydrator\Filter\GetFilter,
+ Zend\Stdlib\Hydrator\Filter\HasFilter;
/**
* @category Zend
@@ -25,6 +29,12 @@ class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
*/
protected $underscoreSeparatedKeys = true;
+ /**
+ * Composite to filter the methods, that need to be hydrated
+ * @var Filter\FilterComposite
+ */
+ protected $filterComposite;
+
/**
* Define if extract values will use camel case or name with underscore
* @param boolean|array $underscoreSeparatedKeys
@@ -33,6 +43,11 @@ public function __construct($underscoreSeparatedKeys = true)
{
parent::__construct();
$this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);
+
+ $this->filterComposite = new FilterComposite();
+ $this->filterComposite->addFilter("is", new IsFilter());
+ $this->filterComposite->addFilter("has", new HasFilter());
+ $this->filterComposite->addFilter("get", new GetFilter());
}
/**
@@ -63,6 +78,7 @@ public function setOptions($options)
public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
{
$this->underscoreSeparatedKeys = $underscoreSeparatedKeys;
+
return $this;
}
@@ -72,6 +88,7 @@ public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
public function getUnderscoreSeparatedKeys()
{
return $this->underscoreSeparatedKeys;
+
}
/**
@@ -99,7 +116,11 @@ public function extract($object)
$methods = get_class_methods($object);
foreach ($methods as $method) {
- if (!preg_match('/^(get|has|is)[A-Z]\w*/', $method)) {
+ if (
+ !$this->filterComposite->filter(
+ get_class($object) . '::' . $method
+ )
+ ) {
continue;
}
@@ -154,4 +175,55 @@ public function hydrate(array $data, $object)
}
return $object;
}
+
+ /**
+ * Add a new filter to take care of what needs to be hydrated.
+ * To exclude e.g. the method getServiceLocator:
+ *
+ * <code>
+ * $composite->addFilter("servicelocator",
+ * function($property) {
+ * list($class, $method) = explode('::', $property);
+ * if ($method === 'getServiceLocator') {
+ * return false;
+ * }
+ * return true;
+ * }, FilterComposite::CONDITION_AND
+ * );
+ * </code>
+ *
+ * @param string $name Index in the composite
+ * @param callable|Zend\Stdlib\Hydrator\Filter\FilterInterface $filter
+ * @param int $condition
+ */
+ public function addFilter($name, $filter, $condition = FilterComposite::CONDITION_OR)
+ {
+ $this->filterComposite->addFilter($name, $filter, $condition);
+ }
+
+ /**
+ * Check whether a specific filter exists at key $name or not
+ *
+ * @param string $name Index in the composite
+ * @return bool
+ */
+ public function hasFilter($name)
+ {
+ return $this->filterComposite->hasFilter($name);
+ }
+
+ /**
+ * Remove a filter from the composition.
+ * To not extract "has" methods, you simply need to unregister it
+ *
+ * <code>
+ * $filterComposite->removeFilter('has');
+ * </code>
+ *
+ * @param $name
+ */
+ public function removeFilter($name)
+ {
+ $this->filterComposite->removeFilter($name);
+ }
}
@@ -0,0 +1,159 @@
+<?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_Service
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+/**
+ * @category Zend
+ * @package Zend_Stdlib
+ * @subpackage Hydrator
+ */
+class FilterComposite implements FilterInterface
+{
+ /**
+ * @var \ArrayObject
+ */
+ protected $orFilter;
+ /**
+ * @var \ArrayObject
+ */
+ protected $andFilter;
+
+ /**
+ * Constant to add with "or" conditition
+ */
+ const CONDITION_OR = 1;
+ /**
+ * Constant to add with "and" conditition
+ */
+ const CONDITION_AND = 2;
+
+ /**
+ * Define default Filter
+ */
+ public function __construct($orFilter = array(), $andFilter = array())
+ {
+ $this->orFilter = new \ArrayObject($orFilter);
+ $this->andFilter = new \ArrayObject($andFilter);
+ }
+
+ /**
+ * Add a filter to the composite. Has to be indexed with $name in
+ * order to identify a specific filter.
+ *
+ * This example will exclude all methods from the hydration, that starts with 'getService'
+ * <code>
+ * $composite->addFilter('exclude',
+ * function($method) {
+ * if (preg_match('/^getService/', $method) {
+ * return false;
+ * }
+ * return true;
+ * }, FilterComposite::CONDITION_AND
+ * );
+ * </code>
+ *
+ * @param string $name
+ * @param callable|FilterInterface $filter
+ * @param int $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND
+ */
+ public function addFilter($name, $filter, $condition = self::CONDITION_OR)
+ {
+ if (
+ is_callable($filter) ||
+ $filter instanceof FilterInterface
+ ) {
+ if ($condition === self::CONDITION_OR) {
+ $this->orFilter[$name] = $filter;
+ }
+ if ($condition === self::CONDITION_AND) {
+ $this->andFilter[$name] = $filter;
+ }
+ }
+ }
+
+ /**
+ * Remove a filter from the composition
+ *
+ * @param $name string Identifier for the filter
+ */
+ public function removeFilter($name)
+ {
+ if( isset($this->orFilter[$name])) {
+ unset($this->orFilter[$name]);
+ }
+
+ if( isset($this->andFilter[$name])) {
+ unset($this->andFilter[$name]);
+ }
+ }
+
+ /**
+ * Check if $name has a filter registered
+ *
+ * @param $name string Identifier for the filter
+ * @return bool
+ */
+ public function hasFilter($name)
+ {
+ return
+ isset($this->orFilter[$name]) || isset($this->andFilter[$name]);
+ }
+
+ /**
+ * Filter the composite based on the AND and OR condition
+ * Will return true if one from the "or conditions" and all from
+ * the "and condition" returns true. Otherwise false
+ *
+ * @param $property string Parameter will be e.g. Parent\Namespace\Class::method
+ * @return bool
+ */
+ public function filter($property)
+ {
+ // return true if no filters are registered
+ if (
+ count($this->orFilter) === 0 &&
+ count($this->andFilter) === 0
+ ) {
+ return true;
+ }
+
+ // Check if 1 from the or filters return true
+ $returnValue = false;
+ foreach($this->orFilter as $filter) {
+ if (is_callable($filter)) {
+ if( $filter($property) === true)
+ {
+ $returnValue = true;
+ break;
+ }
+ } else {
+ if ( $filter->filter($property) === true) {
+ $returnValue = true;
+ break;
+ }
+ }
+ }
+
+ // Check if all of the and condition return true
+ foreach($this->andFilter as $filter) {
+ if (is_callable($filter)) {
+ if( $filter($property) === false) {
+ return false;
+ }
+ } else {
+ if( $filter->filter($property) === false) {
+ return false;
+ }
+ }
+ }
+
+ return $returnValue;
+ }
+}
@@ -0,0 +1,20 @@
+<?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_Service
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+/**
+ * @category Zend
+ * @package Zend_Stdlib
+ * @subpackage Hydrator
+ */
+interface FilterInterface
+{
+ public function filter($property);
+}
@@ -0,0 +1,33 @@
+<?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_Service
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+/**
+ * @category Zend
+ * @package Zend_Stdlib
+ * @subpackage Hydrator
+ */
+class GetFilter implements FilterInterface
+{
+ public function filter($property)
+ {
+ $pos = strpos($property, '::');
+ if ($pos !== false) {
+ $pos += 2;
+ } else {
+ $pos = 0;
+ }
+
+ if (substr($property, $pos, 3) === 'get') {
+ return true;
+ }
+ return false;
+ }
+}
@@ -0,0 +1,33 @@
+<?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_Service
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+/**
+ * @category Zend
+ * @package Zend_Stdlib
+ * @subpackage Hydrator
+ */
+class HasFilter implements FilterInterface
+{
+ public function filter($property)
+ {
+ $pos = strpos($property, '::');
+ if ($pos !== false) {
+ $pos += 2;
+ } else {
+ $pos = 0;
+ }
+
+ if (substr($property, $pos, 3) === 'has') {
+ return true;
+ }
+ return false;
+ }
+}
Oops, something went wrong.

0 comments on commit 0e9664a

Please sign in to comment.