seeder-migration-issues

This commit is contained in:
RafficMohammed
2023-01-30 14:23:34 +05:30
parent 4d918c722f
commit 2ec836b447
3628 changed files with 116006 additions and 187 deletions

View File

@@ -0,0 +1,283 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use ArrayObject;
abstract class AbstractHydrator implements
HydratorInterface,
StrategyEnabledInterface,
FilterEnabledInterface,
NamingStrategyEnabledInterface
{
/**
* The list with strategies that this hydrator has.
*
* @var ArrayObject
*/
protected $strategies;
/**
* An instance of NamingStrategy\NamingStrategyInterface
*
* @var NamingStrategy\NamingStrategyInterface
*/
protected $namingStrategy;
/**
* Composite to filter the methods, that need to be hydrated
*
* @var Filter\FilterComposite
*/
protected $filterComposite;
/**
* Initializes a new instance of this class.
*/
public function __construct()
{
$this->strategies = new ArrayObject();
$this->filterComposite = new Filter\FilterComposite();
}
/**
* Gets the strategy with the given name.
*
* @param string $name The name of the strategy to get.
*
* @throws Exception\InvalidArgumentException
* @return Strategy\StrategyInterface
*/
public function getStrategy($name)
{
if (isset($this->strategies[$name])) {
return $this->strategies[$name];
}
if (!isset($this->strategies['*'])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s: no strategy by name of "%s", and no wildcard strategy present',
__METHOD__,
$name
));
}
return $this->strategies['*'];
}
/**
* Checks if the strategy with the given name exists.
*
* @param string $name The name of the strategy to check for.
* @return bool
*/
public function hasStrategy($name)
{
return array_key_exists($name, $this->strategies)
|| array_key_exists('*', $this->strategies);
}
/**
* Adds the given strategy under the given name.
*
* @param string $name The name of the strategy to register.
* @param Strategy\StrategyInterface $strategy The strategy to register.
* @return HydratorInterface
*/
public function addStrategy($name, Strategy\StrategyInterface $strategy)
{
$this->strategies[$name] = $strategy;
return $this;
}
/**
* Removes the strategy with the given name.
*
* @param string $name The name of the strategy to remove.
* @return HydratorInterface
*/
public function removeStrategy($name)
{
unset($this->strategies[$name]);
return $this;
}
/**
* Converts a value for extraction. If no strategy exists the plain value is returned.
*
* @param string $name The name of the strategy to use.
* @param mixed $value The value that should be converted.
* @param mixed $object The object is optionally provided as context.
* @return mixed
*/
public function extractValue($name, $value, $object = null)
{
if ($this->hasStrategy($name)) {
$strategy = $this->getStrategy($name);
$value = $strategy->extract($value, $object);
}
return $value;
}
/**
* Converts a value for hydration. If no strategy exists the plain value is returned.
*
* @param string $name The name of the strategy to use.
* @param mixed $value The value that should be converted.
* @param array $data The whole data is optionally provided as context.
* @return mixed
*/
public function hydrateValue($name, $value, $data = null)
{
if ($this->hasStrategy($name)) {
$strategy = $this->getStrategy($name);
$value = $strategy->hydrate($value, $data);
}
return $value;
}
/**
* Convert a name for extraction. If no naming strategy exists, the plain value is returned.
*
* @param string $name The name to convert.
* @param null $object The object is optionally provided as context.
* @return mixed
*/
public function extractName($name, $object = null)
{
if ($this->hasNamingStrategy()) {
$name = $this->getNamingStrategy()->extract($name, $object);
}
return $name;
}
/**
* Converts a value for hydration. If no naming strategy exists, the plain value is returned.
*
* @param string $name The name to convert.
* @param array $data The whole data is optionally provided as context.
* @return mixed
*/
public function hydrateName($name, $data = null)
{
if ($this->hasNamingStrategy()) {
$name = $this->getNamingStrategy()->hydrate($name, $data);
}
return $name;
}
/**
* Get the filter instance
*
* @return Filter\FilterComposite
*/
public function getFilter()
{
return $this->filterComposite;
}
/**
* 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|Filter\FilterInterface $filter
* @param int $condition
* @return Filter\FilterComposite
*/
public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR)
{
return $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
* @return Filter\FilterComposite
*/
public function removeFilter($name)
{
return $this->filterComposite->removeFilter($name);
}
/**
* Adds the given naming strategy
*
* @param NamingStrategy\NamingStrategyInterface $strategy The naming to register.
* @return self
*/
public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy)
{
$this->namingStrategy = $strategy;
return $this;
}
/**
* Gets the naming strategy.
*
* @return NamingStrategy\NamingStrategyInterface
*/
public function getNamingStrategy()
{
return $this->namingStrategy;
}
/**
* Checks if a naming strategy exists.
*
* @return bool
*/
public function hasNamingStrategy()
{
return isset($this->namingStrategy);
}
/**
* Removes the naming strategy
*
* @return self
*/
public function removeNamingStrategy()
{
$this->namingStrategy = null;
return $this;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Aggregate;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Hydrator\HydratorInterface;
/**
* Aggregate hydrator that composes multiple hydrators via events
*/
class AggregateHydrator implements HydratorInterface, EventManagerAwareInterface
{
const DEFAULT_PRIORITY = 1;
/**
* @var EventManagerInterface|null
*/
protected $eventManager;
/**
* Attaches the provided hydrator to the list of hydrators to be used while hydrating/extracting data
*
* @param HydratorInterface $hydrator
* @param int $priority
*/
public function add(HydratorInterface $hydrator, $priority = self::DEFAULT_PRIORITY)
{
$this->getEventManager()->attachAggregate(new HydratorListener($hydrator), $priority);
}
/**
* {@inheritDoc}
*/
public function extract($object)
{
$event = new ExtractEvent($this, $object);
$this->getEventManager()->trigger($event);
return $event->getExtractedData();
}
/**
* {@inheritDoc}
*/
public function hydrate(array $data, $object)
{
$event = new HydrateEvent($this, $object, $data);
$this->getEventManager()->trigger($event);
return $event->getHydratedObject();
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers([__CLASS__, get_class($this)]);
$this->eventManager = $eventManager;
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
if (null === $this->eventManager) {
$this->setEventManager(new EventManager());
}
return $this->eventManager;
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Aggregate;
use Zend\EventManager\Event;
/**
* Event triggered when the {@see AggregateHydrator} extracts
* data from an object
*/
class ExtractEvent extends Event
{
const EVENT_EXTRACT = 'extract';
/**
* {@inheritDoc}
*/
protected $name = self::EVENT_EXTRACT;
/**
* @var object
*/
protected $extractionObject;
/**
* @var array
*/
protected $extractedData = [];
/**
* @param object $target
* @param object $extractionObject
*/
public function __construct($target, $extractionObject)
{
$this->target = $target;
$this->extractionObject = $extractionObject;
}
/**
* Retrieves the object from which data is extracted
*
* @return object
*/
public function getExtractionObject()
{
return $this->extractionObject;
}
/**
* @param object $extractionObject
*
* @return void
*/
public function setExtractionObject($extractionObject)
{
$this->extractionObject = $extractionObject;
}
/**
* Retrieves the data that has been extracted
*
* @return array
*/
public function getExtractedData()
{
return $this->extractedData;
}
/**
* @param array $extractedData
*
* @return void
*/
public function setExtractedData(array $extractedData)
{
$this->extractedData = $extractedData;
}
/**
* Merge provided data with the extracted data
*
* @param array $additionalData
*
* @return void
*/
public function mergeExtractedData(array $additionalData)
{
$this->extractedData = array_merge($this->extractedData, $additionalData);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Aggregate;
use Zend\EventManager\Event;
/**
* Event triggered when the {@see AggregateHydrator} hydrates
* data into an object
*/
class HydrateEvent extends Event
{
const EVENT_HYDRATE = 'hydrate';
/**
* {@inheritDoc}
*/
protected $name = self::EVENT_HYDRATE;
/**
* @var object
*/
protected $hydratedObject;
/**
* @var array
*/
protected $hydrationData;
/**
* @param object $target
* @param object $hydratedObject
* @param array $hydrationData
*/
public function __construct($target, $hydratedObject, array $hydrationData)
{
$this->target = $target;
$this->hydratedObject = $hydratedObject;
$this->hydrationData = $hydrationData;
}
/**
* Retrieves the object that is being hydrated
*
* @return object
*/
public function getHydratedObject()
{
return $this->hydratedObject;
}
/**
* @param object $hydratedObject
*/
public function setHydratedObject($hydratedObject)
{
$this->hydratedObject = $hydratedObject;
}
/**
* Retrieves the data that is being used for hydration
*
* @return array
*/
public function getHydrationData()
{
return $this->hydrationData;
}
/**
* @param array $hydrationData
*/
public function setHydrationData(array $hydrationData)
{
$this->hydrationData = $hydrationData;
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Aggregate;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Hydrator\HydratorInterface;
/**
* Aggregate listener wrapping around a hydrator.
*
* Listens to {@see HydrateEvent::EVENT_HYDRATE} and {@see ExtractEvent::EVENT_EXTRACT}
*/
class HydratorListener extends AbstractListenerAggregate
{
/**
* @var HydratorInterface
*/
protected $hydrator;
/**
* @param HydratorInterface $hydrator
*/
public function __construct(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
}
/**
* {@inheritDoc}
*/
public function attach(EventManagerInterface $events, $priority = 1)
{
$this->listeners[] = $events->attach(HydrateEvent::EVENT_HYDRATE, [$this, 'onHydrate'], $priority);
$this->listeners[] = $events->attach(ExtractEvent::EVENT_EXTRACT, [$this, 'onExtract'], $priority);
}
/**
* Callback to be used when {@see HydrateEvent::EVENT_HYDRATE} is triggered
*
* @param HydrateEvent $event
* @return object
* @internal
*/
public function onHydrate(HydrateEvent $event)
{
$object = $this->hydrator->hydrate($event->getHydrationData(), $event->getHydratedObject());
$event->setHydratedObject($object);
return $object;
}
/**
* Callback to be used when {@see ExtractEvent::EVENT_EXTRACT} is triggered
*
* @param ExtractEvent $event
* @return array
* @internal
*/
public function onExtract(ExtractEvent $event)
{
$data = $this->hydrator->extract($event->getExtractionObject());
$event->mergeExtractedData($data);
return $data;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
class ArraySerializable extends AbstractHydrator
{
/**
* Extract values from the provided object
*
* Extracts values via the object's getArrayCopy() method.
*
* @param object $object
* @return array
* @throws Exception\BadMethodCallException for an $object not implementing getArrayCopy()
*/
public function extract($object)
{
if (! is_callable([$object, 'getArrayCopy'])) {
throw new Exception\BadMethodCallException(
sprintf('%s expects the provided object to implement getArrayCopy()', __METHOD__)
);
}
$data = $object->getArrayCopy();
$filter = $this->getFilter();
foreach ($data as $name => $value) {
if (!$filter->filter($name)) {
unset($data[$name]);
continue;
}
$extractedName = $this->extractName($name, $object);
// replace the original key with extracted, if differ
if ($extractedName !== $name) {
unset($data[$name]);
$name = $extractedName;
}
$data[$name] = $this->extractValue($name, $value, $object);
}
return $data;
}
/**
* Hydrate an object
*
* Hydrates an object by passing $data to either its exchangeArray() or
* populate() method.
*
* @param array $data
* @param object $object
* @return object
* @throws Exception\BadMethodCallException for an $object not implementing exchangeArray() or populate()
*/
public function hydrate(array $data, $object)
{
$replacement = [];
foreach ($data as $key => $value) {
$name = $this->hydrateName($key, $data);
$replacement[$name] = $this->hydrateValue($name, $value, $data);
}
if (is_callable([$object, 'exchangeArray'])) {
$object->exchangeArray($replacement);
} elseif (is_callable([$object, 'populate'])) {
$object->populate($replacement);
} else {
throw new Exception\BadMethodCallException(
sprintf('%s expects the provided object to implement exchangeArray() or populate()', __METHOD__)
);
}
return $object;
}
}

View File

@@ -0,0 +1,268 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use Traversable;
use Zend\Stdlib\ArrayUtils;
class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
{
/**
* Holds the names of the methods used for hydration, indexed by class::property name,
* false if the hydration method is not callable/usable for hydration purposes
*
* @var string[]|bool[]
*/
private $hydrationMethodsCache = [];
/**
* A map of extraction methods to property name to be used during extraction, indexed
* by class name and method name
*
* @var string[][]
*/
private $extractionMethodsCache = [];
/**
* Flag defining whether array keys are underscore-separated (true) or camel case (false)
*
* @var bool
*/
protected $underscoreSeparatedKeys = true;
/**
* @var Filter\FilterInterface
*/
private $callableMethodFilter;
/**
* Define if extract values will use camel case or name with underscore
* @param bool|array $underscoreSeparatedKeys
*/
public function __construct($underscoreSeparatedKeys = true)
{
parent::__construct();
$this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);
$this->callableMethodFilter = new Filter\OptionalParametersFilter();
$this->filterComposite->addFilter('is', new Filter\IsFilter());
$this->filterComposite->addFilter('has', new Filter\HasFilter());
$this->filterComposite->addFilter('get', new Filter\GetFilter());
$this->filterComposite->addFilter(
'parameter',
new Filter\OptionalParametersFilter(),
Filter\FilterComposite::CONDITION_AND
);
}
/**
* @param array|Traversable $options
* @return ClassMethods
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (!is_array($options)) {
throw new Exception\InvalidArgumentException(
'The options parameter must be an array or a Traversable'
);
}
if (isset($options['underscoreSeparatedKeys'])) {
$this->setUnderscoreSeparatedKeys($options['underscoreSeparatedKeys']);
}
return $this;
}
/**
* @param bool $underscoreSeparatedKeys
* @return ClassMethods
*/
public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
{
$this->underscoreSeparatedKeys = (bool) $underscoreSeparatedKeys;
if ($this->underscoreSeparatedKeys) {
$this->setNamingStrategy(new NamingStrategy\UnderscoreNamingStrategy);
} elseif ($this->getNamingStrategy() instanceof NamingStrategy\UnderscoreNamingStrategy) {
$this->removeNamingStrategy();
}
return $this;
}
/**
* @return bool
*/
public function getUnderscoreSeparatedKeys()
{
return $this->underscoreSeparatedKeys;
}
/**
* Extract values from an object with class methods
*
* Extracts the getter/setter of the given $object.
*
* @param object $object
* @return array
* @throws Exception\BadMethodCallException for a non-object $object
*/
public function extract($object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
));
}
$objectClass = get_class($object);
// reset the hydrator's hydrator's cache for this object, as the filter may be per-instance
if ($object instanceof Filter\FilterProviderInterface) {
$this->extractionMethodsCache[$objectClass] = null;
}
// pass 1 - finding out which properties can be extracted, with which methods (populate hydration cache)
if (! isset($this->extractionMethodsCache[$objectClass])) {
$this->extractionMethodsCache[$objectClass] = [];
$filter = $this->filterComposite;
$methods = get_class_methods($object);
if ($object instanceof Filter\FilterProviderInterface) {
$filter = new Filter\FilterComposite(
[$object->getFilter()],
[new Filter\MethodMatchFilter('getFilter')]
);
}
foreach ($methods as $method) {
$methodFqn = $objectClass . '::' . $method;
if (! ($filter->filter($methodFqn) && $this->callableMethodFilter->filter($methodFqn))) {
continue;
}
$attribute = $method;
if (strpos($method, 'get') === 0) {
$attribute = substr($method, 3);
if (!property_exists($object, $attribute)) {
$attribute = lcfirst($attribute);
}
}
$this->extractionMethodsCache[$objectClass][$method] = $attribute;
}
}
$values = [];
// pass 2 - actually extract data
foreach ($this->extractionMethodsCache[$objectClass] as $methodName => $attributeName) {
$realAttributeName = $this->extractName($attributeName, $object);
$values[$realAttributeName] = $this->extractValue($realAttributeName, $object->$methodName(), $object);
}
return $values;
}
/**
* Hydrate an object by populating getter/setter methods
*
* Hydrates an object by getter/setter methods of the object.
*
* @param array $data
* @param object $object
* @return object
* @throws Exception\BadMethodCallException for a non-object $object
*/
public function hydrate(array $data, $object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
));
}
$objectClass = get_class($object);
foreach ($data as $property => $value) {
$propertyFqn = $objectClass . '::$' . $property;
if (! isset($this->hydrationMethodsCache[$propertyFqn])) {
$setterName = 'set' . ucfirst($this->hydrateName($property, $data));
$this->hydrationMethodsCache[$propertyFqn] = is_callable([$object, $setterName])
? $setterName
: false;
}
if ($this->hydrationMethodsCache[$propertyFqn]) {
$object->{$this->hydrationMethodsCache[$propertyFqn]}($this->hydrateValue($property, $value, $data));
}
}
return $object;
}
/**
* {@inheritDoc}
*/
public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR)
{
$this->resetCaches();
return parent::addFilter($name, $filter, $condition);
}
/**
* {@inheritDoc}
*/
public function removeFilter($name)
{
$this->resetCaches();
return parent::removeFilter($name);
}
/**
* {@inheritDoc}
*/
public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy)
{
$this->resetCaches();
return parent::setNamingStrategy($strategy);
}
/**
* {@inheritDoc}
*/
public function removeNamingStrategy()
{
$this->resetCaches();
return parent::removeNamingStrategy();
}
/**
* Reset all local hydration/extraction caches
*/
private function resetCaches()
{
$this->hydrationMethodsCache = $this->extractionMethodsCache = [];
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use Zend\ServiceManager\ServiceLocatorInterface;
class DelegatingHydrator implements HydratorInterface
{
/**
* @var ServiceLocatorInterface
*/
protected $hydrators;
/**
* Constructor
*
* @param ServiceLocatorInterface $hydrators
*/
public function __construct(ServiceLocatorInterface $hydrators)
{
$this->hydrators = $hydrators;
}
/**
* {@inheritdoc}
*/
public function hydrate(array $data, $object)
{
return $this->getHydrator($object)->hydrate($data, $object);
}
/**
* {@inheritdoc}
*/
public function extract($object)
{
return $this->getHydrator($object)->extract($object);
}
/**
* Gets hydrator of an object
*
* @param object $object
* @return HydratorInterface
*/
protected function getHydrator($object)
{
return $this->hydrators->get(get_class($object));
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class DelegatingHydratorFactory implements FactoryInterface
{
/**
* Creates DelegatingHydrator
*
* @param ServiceLocatorInterface $serviceLocator
* @return DelegatingHydrator
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
// Assume that this factory is registered with the HydratorManager,
// and just pass it directly on.
return new DelegatingHydrator($serviceLocator);
}
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Bad method call exception
*/
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Domain exception
*/
class DomainException extends \DomainException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Exception marker interface
*/
interface ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Extension not loaded exception
*/
class ExtensionNotLoadedException extends RuntimeException
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Invalid Argument Exception
*/
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Invalid callback exception
*/
class InvalidCallbackException extends DomainException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Logic exception
*/
class LogicException extends \LogicException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Exception;
/**
* Runtime exception
*/
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface ExtractionInterface
{
/**
* Extract values from an object
*
* @param object $object
* @return array
*/
public function extract($object);
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
use ArrayObject;
use Zend\Hydrator\Exception\InvalidArgumentException;
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
*
* @param array $orFilter
* @param array $andFilter
* @throws InvalidArgumentException
*/
public function __construct($orFilter = [], $andFilter = [])
{
array_walk(
$orFilter,
function ($value, $key) {
if (!is_callable($value) && !$value instanceof FilterInterface) {
throw new InvalidArgumentException(
'The value of ' . $key . ' should be either a callable or ' .
'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
);
}
}
);
array_walk(
$andFilter,
function ($value, $key) {
if (!is_callable($value) && !$value instanceof FilterInterface) {
throw new InvalidArgumentException(
'The value of ' . $key . ' should be either a callable or ' .
'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
);
}
}
);
$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
* @throws InvalidArgumentException
* @return FilterComposite
*/
public function addFilter($name, $filter, $condition = self::CONDITION_OR)
{
if (!is_callable($filter) && !($filter instanceof FilterInterface)) {
throw new InvalidArgumentException(
'The value of ' . $name . ' should be either a callable or ' .
'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
);
}
if ($condition === self::CONDITION_OR) {
$this->orFilter[$name] = $filter;
} elseif ($condition === self::CONDITION_AND) {
$this->andFilter[$name] = $filter;
}
return $this;
}
/**
* Remove a filter from the composition
*
* @param $name string Identifier for the filter
* @return FilterComposite
*/
public function removeFilter($name)
{
if (isset($this->orFilter[$name])) {
unset($this->orFilter[$name]);
}
if (isset($this->andFilter[$name])) {
unset($this->andFilter[$name]);
}
return $this;
}
/**
* 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)
{
$andCount = count($this->andFilter);
$orCount = count($this->orFilter);
// return true if no filters are registered
if ($orCount === 0 && $andCount === 0) {
return true;
} elseif ($orCount === 0 && $andCount !== 0) {
$returnValue = true;
} else {
$returnValue = false;
}
// Check if 1 from the or filters return true
foreach ($this->orFilter as $filter) {
if (is_callable($filter)) {
if ($filter($property) === true) {
$returnValue = true;
break;
}
continue;
} 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;
}
continue;
} else {
if ($filter->filter($property) === false) {
return false;
}
}
}
return $returnValue;
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
interface FilterInterface
{
/**
* Should return true, if the given filter
* does not match
*
* @param string $property The name of the property
* @return bool
*/
public function filter($property);
}

View File

@@ -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-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
interface FilterProviderInterface
{
/**
* Provides a filter for hydration
*
* @return FilterInterface
*/
public function getFilter();
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
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;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
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;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
class IsFilter implements FilterInterface
{
public function filter($property)
{
$pos = strpos($property, '::');
if ($pos !== false) {
$pos += 2;
} else {
$pos = 0;
}
if (substr($property, $pos, 2) === 'is') {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
class MethodMatchFilter implements FilterInterface
{
/**
* The method to exclude
* @var string
*/
protected $method = null;
/**
* Either an exclude or an include
* @var bool
*/
protected $exclude = null;
/**
* @param string $method The method to exclude or include
* @param bool $exclude If the method should be excluded
*/
public function __construct($method, $exclude = true)
{
$this->method = $method;
$this->exclude = $exclude;
}
public function filter($property)
{
$pos = strpos($property, '::');
if ($pos !== false) {
$pos += 2;
} else {
$pos = 0;
}
if (substr($property, $pos) === $this->method) {
return !$this->exclude;
}
return $this->exclude;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
use ReflectionException;
use ReflectionMethod;
use Zend\Hydrator\Exception\InvalidArgumentException;
class NumberOfParameterFilter implements FilterInterface
{
/**
* The number of parameters beeing accepted
* @var int
*/
protected $numberOfParameters = null;
/**
* @param int $numberOfParameters Number of accepted parameters
*/
public function __construct($numberOfParameters = 0)
{
$this->numberOfParameters = (int) $numberOfParameters;
}
/**
* @param string $property the name of the property
* @return bool
* @throws InvalidArgumentException
*/
public function filter($property)
{
try {
$reflectionMethod = new ReflectionMethod($property);
} catch (ReflectionException $exception) {
throw new InvalidArgumentException(
"Method $property doesn't exist"
);
}
return $reflectionMethod->getNumberOfParameters() === $this->numberOfParameters;
}
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Filter;
use ReflectionException;
use ReflectionMethod;
use ReflectionParameter;
use Zend\Hydrator\Exception\InvalidArgumentException;
/**
* Filter that includes methods which have no parameters or only optional parameters
*/
class OptionalParametersFilter implements FilterInterface
{
/**
* Map of methods already analyzed
* by {@see OptionalParametersFilter::filter()},
* cached for performance reasons
*
* @var bool[]
*/
protected static $propertiesCache = [];
/**
* {@inheritDoc}
*/
public function filter($property)
{
if (isset(static::$propertiesCache[$property])) {
return static::$propertiesCache[$property];
}
try {
$reflectionMethod = new ReflectionMethod($property);
} catch (ReflectionException $exception) {
throw new InvalidArgumentException(sprintf('Method %s doesn\'t exist', $property));
}
$mandatoryParameters = array_filter(
$reflectionMethod->getParameters(),
function (ReflectionParameter $parameter) {
return ! $parameter->isOptional();
}
);
return static::$propertiesCache[$property] = empty($mandatoryParameters);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface FilterEnabledInterface extends Filter\FilterProviderInterface
{
/**
* 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|Filter\FilterInterface $filter
* @param int $condition
* @return Filter\FilterComposite
*/
public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR);
/**
* Check whether a specific filter exists at key $name or not
*
* @param string $name Index in the composite
* @return bool
*/
public function 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
* @return Filter\FilterComposite
*/
public function removeFilter($name);
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface HydrationInterface
{
/**
* Hydrate $object with the provided $data.
*
* @param array $data
* @param object $object
* @return object
*/
public function hydrate(array $data, $object);
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface HydratorAwareInterface
{
/**
* Set hydrator
*
* @param HydratorInterface $hydrator
* @return HydratorAwareInterface
*/
public function setHydrator(HydratorInterface $hydrator);
/**
* Retrieve hydrator
*
* @return HydratorInterface
*/
public function getHydrator();
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
trait HydratorAwareTrait
{
/**
* Hydrator instance
*
* @var HydratorInterface
* @access protected
*/
protected $hydrator = null;
/**
* Set hydrator
*
* @param HydratorInterface $hydrator
* @return self
* @access public
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
return $this;
}
/**
* Retrieve hydrator
*
* @param void
* @return null|HydratorInterface
* @access public
*/
public function getHydrator()
{
return $this->hydrator;
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface HydratorInterface extends HydrationInterface, ExtractionInterface
{
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use Traversable;
interface HydratorOptionsInterface
{
/**
* @param array|Traversable $options
* @return self
*/
public function setOptions($options);
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use Zend\ServiceManager\AbstractPluginManager;
/**
* Plugin manager implementation for hydrators.
*
* Enforces that adapters retrieved are instances of HydratorInterface
*/
class HydratorPluginManager extends AbstractPluginManager
{
/**
* Whether or not to share by default
*
* @var bool
*/
protected $shareByDefault = false;
/**
* Default aliases
*
* @var array
*/
protected $aliases = [
'delegatinghydrator' => 'Zend\Hydrator\DelegatingHydrator',
];
/**
* Default set of adapters
*
* @var array
*/
protected $invokableClasses = [
'arrayserializable' => 'Zend\Hydrator\ArraySerializable',
'classmethods' => 'Zend\Hydrator\ClassMethods',
'objectproperty' => 'Zend\Hydrator\ObjectProperty',
'reflection' => 'Zend\Hydrator\Reflection'
];
/**
* Default factory-based adapters
*
* @var array
*/
protected $factories = [
'Zend\Hydrator\DelegatingHydrator' => 'Zend\Hydrator\DelegatingHydratorFactory',
];
/**
* {@inheritDoc}
*/
public function validatePlugin($plugin)
{
if ($plugin instanceof HydratorInterface) {
// we're okay
return;
}
throw new Exception\RuntimeException(sprintf(
'Plugin of type %s is invalid; must implement Zend\Hydrator\HydratorInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin))
));
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Iterator;
use ArrayIterator;
use Zend\Hydrator\HydratorInterface;
class HydratingArrayIterator extends HydratingIteratorIterator
{
/**
* @var HydratorInterface
*/
protected $hydrator;
/**
* @var object
*/
protected $prototype;
/**
* @param HydratorInterface $hydrator
* @param array $data
* @param string|object $prototype Object, or class name to use for prototype.
*/
public function __construct(HydratorInterface $hydrator, array $data, $prototype)
{
parent::__construct($hydrator, new ArrayIterator($data), $prototype);
}
}

View File

@@ -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-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Iterator;
use Iterator;
use Zend\Hydrator\HydratorInterface;
interface HydratingIteratorInterface extends Iterator
{
/**
* This sets the prototype to hydrate.
*
* This prototype can be the name of the class or the object itself;
* iteration will clone the object.
*
* @param string|object $prototype
*/
public function setPrototype($prototype);
/**
* Sets the hydrator to use during iteration.
*
* @param HydratorInterface $hydrator
*/
public function setHydrator(HydratorInterface $hydrator);
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Iterator;
use Iterator;
use IteratorIterator;
use Zend\Hydrator\Exception\InvalidArgumentException;
use Zend\Hydrator\HydratorInterface;
class HydratingIteratorIterator extends IteratorIterator implements HydratingIteratorInterface
{
/**
* @var HydratorInterface
*/
protected $hydrator;
/**
* @var object
*/
protected $prototype;
/**
* @param HydratorInterface $hydrator
* @param Iterator $data
* @param string|object $prototype Object or class name to use for prototype.
*/
public function __construct(HydratorInterface $hydrator, Iterator $data, $prototype)
{
$this->setHydrator($hydrator);
$this->setPrototype($prototype);
parent::__construct($data);
}
/**
* @inheritdoc
*/
public function setPrototype($prototype)
{
if (is_object($prototype)) {
$this->prototype = $prototype;
return;
}
if (!class_exists($prototype)) {
throw new InvalidArgumentException(
sprintf('Method %s was passed an invalid class name: %s', __METHOD__, $prototype)
);
}
$this->prototype = new $prototype;
}
/**
* @inheritdoc
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
}
/**
* @return object Returns hydrated clone of $prototype
*/
public function current()
{
$currentValue = parent::current();
$object = clone $this->prototype;
$this->hydrator->hydrate($currentValue, $object);
return $object;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
class ArrayMapNamingStrategy implements NamingStrategyInterface
{
/**
* @var string[]
*/
private $extractionMap = [];
/**
* @var string[]
*/
private $hydrationMap = [];
/**
* Constructor
*
* @param array $extractionMap A map of string keys and values for symmetric translation of hydrated
* and extracted field names
*/
public function __construct(array $extractionMap)
{
$this->extractionMap = $extractionMap;
$this->hydrationMap = array_flip($extractionMap);
}
/**
* {@inheritDoc}
*/
public function hydrate($name)
{
return isset($this->hydrationMap[$name]) ? $this->hydrationMap[$name] : $name;
}
/**
* {@inheritDoc}
*/
public function extract($name)
{
return isset($this->extractionMap[$name]) ? $this->extractionMap[$name] : $name;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
class CompositeNamingStrategy implements NamingStrategyInterface
{
/**
* @var array
*/
private $namingStrategies = [];
/**
* @var NamingStrategyInterface
*/
private $defaultNamingStrategy;
/**
* @param NamingStrategyInterface[] $strategies indexed by the name they translate
* @param NamingStrategyInterface|null $defaultNamingStrategy
*/
public function __construct(array $strategies, NamingStrategyInterface $defaultNamingStrategy = null)
{
$this->namingStrategies = array_map(
function (NamingStrategyInterface $strategy) {
// this callback is here only to ensure type-safety
return $strategy;
},
$strategies
);
$this->defaultNamingStrategy = $defaultNamingStrategy ?: new IdentityNamingStrategy();
}
/**
* {@inheritDoc}
*/
public function extract($name)
{
$strategy = isset($this->namingStrategies[$name])
? $this->namingStrategies[$name]
: $this->defaultNamingStrategy;
return $strategy->extract($name);
}
/**
* {@inheritDoc}
*/
public function hydrate($name)
{
$strategy = isset($this->namingStrategies[$name])
? $this->namingStrategies[$name]
: $this->defaultNamingStrategy;
return $strategy->hydrate($name);
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
class IdentityNamingStrategy implements NamingStrategyInterface
{
/**
* {@inheritDoc}
*/
public function hydrate($name)
{
return $name;
}
/**
* {@inheritDoc}
*/
public function extract($name)
{
return $name;
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
use Zend\Hydrator\Exception\InvalidArgumentException;
class MapNamingStrategy implements NamingStrategyInterface
{
/**
* Map for hydrate name conversion.
*
* @var array
*/
protected $mapping = [];
/**
* Reversed map for extract name conversion.
*
* @var array
*/
protected $reverse = [];
/**
* Initialize.
*
* @param array $mapping Map for name conversion on hydration
* @param array $reverse Reverse map for name conversion on extraction
*/
public function __construct(array $mapping, array $reverse = null)
{
$this->mapping = $mapping;
$this->reverse = $reverse ?: $this->flipMapping($mapping);
}
/**
* Safelly flip mapping array.
*
* @param array $array Array to flip
* @return array Flipped array
* @throws InvalidArgumentException
*/
protected function flipMapping(array $array)
{
array_walk($array, function ($value) {
if (!is_string($value) && !is_int($value)) {
throw new InvalidArgumentException('Mapping array can\'t be flipped because of invalid value');
}
});
return array_flip($array);
}
/**
* Converts the given name so that it can be extracted by the hydrator.
*
* @param string $name The original name
* @return mixed The hydrated name
*/
public function hydrate($name)
{
if (array_key_exists($name, $this->mapping)) {
return $this->mapping[$name];
}
return $name;
}
/**
* Converts the given name so that it can be hydrated by the hydrator.
*
* @param string $name The original name
* @return mixed The extracted name
*/
public function extract($name)
{
if (array_key_exists($name, $this->reverse)) {
return $this->reverse[$name];
}
return $name;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
/**
* Allow property extraction / hydration for hydrator
*/
interface NamingStrategyInterface
{
/**
* Converts the given name so that it can be extracted by the hydrator.
*
* @param string $name The original name
* @param object $object (optional) The original object for context.
* @return mixed The hydrated name
*/
public function hydrate($name);
/**
* Converts the given name so that it can be hydrated by the hydrator.
*
* @param string $name The original name
* @param array $data (optional) The original data for context.
* @return mixed The extracted name
*/
public function extract($name);
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\NamingStrategy;
use Zend\Filter\FilterChain;
class UnderscoreNamingStrategy implements NamingStrategyInterface
{
/**
* @var FilterChain|null
*/
protected static $camelCaseToUnderscoreFilter;
/**
* @var FilterChain|null
*/
protected static $underscoreToStudlyCaseFilter;
/**
* Remove underscores and capitalize letters
*
* @param string $name
* @return string
*/
public function hydrate($name)
{
return $this->getUnderscoreToStudlyCaseFilter()->filter($name);
}
/**
* Remove capitalized letters and prepend underscores.
*
* @param string $name
* @return string
*/
public function extract($name)
{
return $this->getCamelCaseToUnderscoreFilter()->filter($name);
}
/**
* @return FilterChain
*/
protected function getUnderscoreToStudlyCaseFilter()
{
if (static::$underscoreToStudlyCaseFilter instanceof FilterChain) {
return static::$underscoreToStudlyCaseFilter;
}
$filter = new FilterChain();
$filter->attachByName('WordUnderscoreToStudlyCase');
return static::$underscoreToStudlyCaseFilter = $filter;
}
/**
* @return FilterChain
*/
protected function getCamelCaseToUnderscoreFilter()
{
if (static::$camelCaseToUnderscoreFilter instanceof FilterChain) {
return static::$camelCaseToUnderscoreFilter;
}
$filter = new FilterChain();
$filter->attachByName('WordCamelCaseToUnderscore');
$filter->attachByName('StringToLower');
return static::$camelCaseToUnderscoreFilter = $filter;
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface NamingStrategyEnabledInterface
{
/**
* Adds the given naming strategy
*
* @param NamingStrategy\NamingStrategyInterface $strategy The naming to register.
* @return self
*/
public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy);
/**
* Gets the naming strategy.
*
* @return NamingStrategy\NamingStrategyInterface
*/
public function getNamingStrategy();
/**
* Checks if a naming strategy exists.
*
* @return bool
*/
public function hasNamingStrategy();
/**
* Removes the naming with the given name.
*
* @return self
*/
public function removeNamingStrategy();
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use ReflectionClass;
use ReflectionProperty;
class ObjectProperty extends AbstractHydrator
{
/**
* @var array[] indexed by class name and then property name
*/
private static $skippedPropertiesCache = [];
/**
* {@inheritDoc}
*
* Extracts the accessible non-static properties of the given $object.
*
* @throws Exception\BadMethodCallException for a non-object $object
*/
public function extract($object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(
sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
);
}
$data = get_object_vars($object);
$filter = $this->getFilter();
foreach ($data as $name => $value) {
// Filter keys, removing any we don't want
if (! $filter->filter($name)) {
unset($data[$name]);
continue;
}
// Replace name if extracted differ
$extracted = $this->extractName($name, $object);
if ($extracted !== $name) {
unset($data[$name]);
$name = $extracted;
}
$data[$name] = $this->extractValue($name, $value, $object);
}
return $data;
}
/**
* {@inheritDoc}
*
* Hydrate an object by populating public properties
*
* Hydrates an object by setting public properties of the object.
*
* @throws Exception\BadMethodCallException for a non-object $object
*/
public function hydrate(array $data, $object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(
sprintf('%s expects the provided $object to be a PHP object)', __METHOD__)
);
}
$properties = & self::$skippedPropertiesCache[get_class($object)];
if (! isset($properties)) {
$reflection = new ReflectionClass($object);
$properties = array_fill_keys(
array_map(
function (ReflectionProperty $property) {
return $property->getName();
},
$reflection->getProperties(
ReflectionProperty::IS_PRIVATE
+ ReflectionProperty::IS_PROTECTED
+ ReflectionProperty::IS_STATIC
)
),
true
);
}
foreach ($data as $name => $value) {
$property = $this->hydrateName($name, $data);
if (isset($properties[$property])) {
continue;
}
$object->$property = $this->hydrateValue($property, $value, $data);
}
return $object;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
use ReflectionClass;
use ReflectionProperty;
class Reflection extends AbstractHydrator
{
/**
* Simple in-memory array cache of ReflectionProperties used.
* @var ReflectionProperty[]
*/
protected static $reflProperties = [];
/**
* Extract values from an object
*
* @param object $object
* @return array
*/
public function extract($object)
{
$result = [];
foreach (self::getReflProperties($object) as $property) {
$propertyName = $this->extractName($property->getName(), $object);
if (!$this->filterComposite->filter($propertyName)) {
continue;
}
$value = $property->getValue($object);
$result[$propertyName] = $this->extractValue($propertyName, $value, $object);
}
return $result;
}
/**
* Hydrate $object with the provided $data.
*
* @param array $data
* @param object $object
* @return object
*/
public function hydrate(array $data, $object)
{
$reflProperties = self::getReflProperties($object);
foreach ($data as $key => $value) {
$name = $this->hydrateName($key, $data);
if (isset($reflProperties[$name])) {
$reflProperties[$name]->setValue($object, $this->hydrateValue($name, $value, $data));
}
}
return $object;
}
/**
* Get a reflection properties from in-memory cache and lazy-load if
* class has not been loaded.
*
* @param string|object $input
* @throws Exception\InvalidArgumentException
* @return ReflectionProperty[]
*/
protected static function getReflProperties($input)
{
if (is_object($input)) {
$input = get_class($input);
} elseif (!is_string($input)) {
throw new Exception\InvalidArgumentException('Input must be a string or an object.');
}
if (isset(static::$reflProperties[$input])) {
return static::$reflProperties[$input];
}
static::$reflProperties[$input] = [];
$reflClass = new ReflectionClass($input);
$reflProperties = $reflClass->getProperties();
foreach ($reflProperties as $property) {
$property->setAccessible(true);
static::$reflProperties[$input][$property->getName()] = $property;
}
return static::$reflProperties[$input];
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
use Zend\Hydrator\Exception\InvalidArgumentException;
/**
* This Strategy extracts and hydrates int and string values to Boolean values
*/
class BooleanStrategy implements StrategyInterface
{
/**
* @var int|string
*/
private $trueValue;
/**
* @var int|string
*/
private $falseValue;
/**
* @param int|string $trueValue
* @param int|string $falseValue
* @throws InvalidArgumentException
*/
public function __construct($trueValue, $falseValue)
{
if (!is_int($trueValue) && !is_string($trueValue)) {
throw new InvalidArgumentException(sprintf(
'Unable to instantiate BooleanStrategy. Expected int or string as $trueValue. %s was given',
is_object($trueValue) ? get_class($trueValue) : gettype($trueValue)
));
}
if (!is_int($falseValue) && !is_string($falseValue)) {
throw new InvalidArgumentException(sprintf(
'Unable to instantiate BooleanStrategy. Expected int or string as $falseValue. %s was given',
is_object($falseValue) ? get_class($falseValue) : gettype($falseValue)
));
}
$this->trueValue = $trueValue;
$this->falseValue = $falseValue;
}
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param bool $value The original value.
* @throws InvalidArgumentException
* @return int|string Returns the value that should be extracted.
*/
public function extract($value)
{
if (!is_bool($value)) {
throw new InvalidArgumentException(sprintf(
'Unable to extract. Expected bool. %s was given.',
is_object($value) ? get_class($value) : gettype($value)
));
}
return $value === true ? $this->trueValue : $this->falseValue;
}
/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param int|string $value The original value.
* @throws InvalidArgumentException
* @return bool Returns the value that should be hydrated.
*/
public function hydrate($value)
{
if (!is_string($value) && !is_int($value)) {
throw new InvalidArgumentException(sprintf(
'Unable to hydrate. Expected string or int. %s was given.',
is_object($value) ? get_class($value) : gettype($value)
));
}
if ($value === $this->trueValue) {
return true;
}
if ($value === $this->falseValue) {
return false;
}
throw new InvalidArgumentException(sprintf(
'Unexpected value %s can\'t be hydrated. Expect %s or %s as Value.',
$value,
$this->trueValue,
$this->falseValue
));
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
class ClosureStrategy implements StrategyInterface
{
/**
* Function, used in extract method, default:
*
* <code>
* function ($value) {
* return $value;
* };
* </code>
*
* @var callable
*/
protected $extractFunc = null;
/**
* Function, used in hydrate method, default:
*
* <code>
* function ($value) {
* return $value;
* };
* </code>
*
* @var callable
*/
protected $hydrateFunc = null;
/**
* You can describe how your values will extract and hydrate, like this:
*
* <code>
* $hydrator->addStrategy('category', new ClosureStrategy(
* function (Category $value) {
* return (int) $value->id;
* },
* function ($value) {
* return new Category((int) $value);
* }
* ));
* </code>
*
* @param callable $extractFunc - anonymous function, that extract values
* from object
* @param callable $hydrateFunc - anonymous function, that hydrate values
* into object
*/
public function __construct($extractFunc = null, $hydrateFunc = null)
{
if (isset($extractFunc)) {
if (!is_callable($extractFunc)) {
throw new \Exception('$extractFunc must be callable');
}
$this->extractFunc = $extractFunc;
} else {
$this->extractFunc = function ($value) {
return $value;
};
}
if (isset($hydrateFunc)) {
if (!is_callable($hydrateFunc)) {
throw new \Exception('$hydrateFunc must be callable');
}
$this->hydrateFunc = $hydrateFunc;
} else {
$this->hydrateFunc = function ($value) {
return $value;
};
}
}
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @param array $object The object is optionally provided as context.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value, $object = null)
{
$func = $this->extractFunc;
return $func($value, $object);
}
/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @param array $data The whole data is optionally provided as context.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value, $data = null)
{
$func = $this->hydrateFunc;
return $func($value, $data);
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
use DateTime;
use DateTimeZone;
class DateTimeFormatterStrategy implements StrategyInterface
{
/**
* @var string
*/
private $format;
/**
* @var DateTimeZone|null
*/
private $timezone;
/**
* Constructor
*
* @param string $format
* @param DateTimeZone|null $timezone
*/
public function __construct($format = DateTime::RFC3339, DateTimeZone $timezone = null)
{
$this->format = (string) $format;
$this->timezone = $timezone;
}
/**
* {@inheritDoc}
*
* Converts to date time string
*
* @param mixed|DateTime $value
*
* @return mixed|string
*/
public function extract($value)
{
if ($value instanceof DateTime) {
return $value->format($this->format);
}
return $value;
}
/**
* Converts date time string to DateTime instance for injecting to object
*
* {@inheritDoc}
*
* @param mixed|string $value
*
* @return mixed|DateTime
*/
public function hydrate($value)
{
if ($value === '' || $value === null) {
return;
}
if ($this->timezone) {
$hydrated = DateTime::createFromFormat($this->format, $value, $this->timezone);
} else {
$hydrated = DateTime::createFromFormat($this->format, $value);
}
return $hydrated ?: $value;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
class DefaultStrategy implements StrategyInterface
{
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value)
{
return $value;
}
/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value)
{
return $value;
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy\Exception;
interface ExceptionInterface
{
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy\Exception;
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
class ExplodeStrategy implements StrategyInterface
{
/**
* @var string
*/
private $valueDelimiter;
/**
* @var int|null
*/
private $explodeLimit;
/**
* Constructor
*
* @param string $delimiter String that the values will be split upon
* @param int|null $explodeLimit Explode limit
*/
public function __construct($delimiter = ',', $explodeLimit = null)
{
$this->setValueDelimiter($delimiter);
$this->explodeLimit = ($explodeLimit === null) ? null : (int) $explodeLimit;
}
/**
* Sets the delimiter string that the values will be split upon
*
* @param string $delimiter
* @return self
*/
private function setValueDelimiter($delimiter)
{
if (!is_string($delimiter)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects Delimiter to be string, %s provided instead',
__METHOD__,
is_object($delimiter) ? get_class($delimiter) : gettype($delimiter)
));
}
if (empty($delimiter)) {
throw new Exception\InvalidArgumentException('Delimiter cannot be empty.');
}
$this->valueDelimiter = $delimiter;
}
/**
* {@inheritDoc}
*
* Split a string by delimiter
*
* @param string|null $value
*
* @return string[]
*
* @throws Exception\InvalidArgumentException
*/
public function hydrate($value)
{
if (null === $value) {
return [];
}
if (!(is_string($value) || is_numeric($value))) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects argument 1 to be string, %s provided instead',
__METHOD__,
is_object($value) ? get_class($value) : gettype($value)
));
}
if ($this->explodeLimit !== null) {
return explode($this->valueDelimiter, $value, $this->explodeLimit);
}
return explode($this->valueDelimiter, $value);
}
/**
* {@inheritDoc}
*
* Join array elements with delimiter
*
* @param string[] $value The original value.
*
* @return string|null
*/
public function extract($value)
{
if (!is_array($value)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects argument 1 to be array, %s provided instead',
__METHOD__,
is_object($value) ? get_class($value) : gettype($value)
));
}
return empty($value) ? null : implode($this->valueDelimiter, $value);
}
}

View File

@@ -0,0 +1,123 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
use Zend\Hydrator\Exception\InvalidArgumentException;
use Zend\Serializer\Adapter\AdapterInterface as SerializerAdapter;
use Zend\Serializer\Serializer as SerializerFactory;
class SerializableStrategy implements StrategyInterface
{
/**
* @var string|SerializerAdapter
*/
protected $serializer;
/**
* @var array
*/
protected $serializerOptions = [];
/**
*
* @param mixed $serializer string or SerializerAdapter
* @param mixed $serializerOptions
*/
public function __construct($serializer, $serializerOptions = null)
{
$this->setSerializer($serializer);
if ($serializerOptions) {
$this->setSerializerOptions($serializerOptions);
}
}
/**
* Serialize the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value)
{
$serializer = $this->getSerializer();
return $serializer->serialize($value);
}
/**
* Unserialize the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value)
{
$serializer = $this->getSerializer();
return $serializer->unserialize($value);
}
/**
* Set serializer
*
* @param string|SerializerAdapter $serializer
* @return SerializableStrategy
*/
public function setSerializer($serializer)
{
if (!is_string($serializer) && !$serializer instanceof SerializerAdapter) {
throw new InvalidArgumentException(sprintf(
'%s expects either a string serializer name or Zend\Serializer\Adapter\AdapterInterface instance; '
. 'received "%s"',
__METHOD__,
(is_object($serializer) ? get_class($serializer) : gettype($serializer))
));
}
$this->serializer = $serializer;
return $this;
}
/**
* Get serializer
*
* @return SerializerAdapter
*/
public function getSerializer()
{
if (is_string($this->serializer)) {
$options = $this->getSerializerOptions();
$this->setSerializer(SerializerFactory::factory($this->serializer, $options));
} elseif (null === $this->serializer) {
$this->setSerializer(SerializerFactory::getDefaultAdapter());
}
return $this->serializer;
}
/**
* Set configuration options for instantiating a serializer adapter
*
* @param mixed $serializerOptions
* @return SerializableStrategy
*/
public function setSerializerOptions($serializerOptions)
{
$this->serializerOptions = $serializerOptions;
return $this;
}
/**
* Get configuration options for instantiating a serializer adapter
*
* @return mixed
*/
public function getSerializerOptions()
{
return $this->serializerOptions;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
use Traversable;
use Zend\Stdlib\ArrayUtils;
class StrategyChain implements StrategyInterface
{
/**
* Strategy chain for extraction
*
* @var StrategyInterface[]
*/
private $extractionStrategies;
/**
* Strategy chain for hydration
*
* @var StrategyInterface[]
*/
private $hydrationStrategies;
/**
* Constructor
*
* @param array|Traversable $extractionStrategies
*/
public function __construct($extractionStrategies)
{
$extractionStrategies = ArrayUtils::iteratorToArray($extractionStrategies);
$this->extractionStrategies = array_map(
function (StrategyInterface $strategy) {
// this callback is here only to ensure type-safety
return $strategy;
},
$extractionStrategies
);
$this->hydrationStrategies = array_reverse($extractionStrategies);
}
/**
* {@inheritDoc}
*/
public function extract($value)
{
foreach ($this->extractionStrategies as $strategy) {
$value = $strategy->extract($value);
}
return $value;
}
/**
* {@inheritDoc}
*/
public function hydrate($value)
{
foreach ($this->hydrationStrategies as $strategy) {
$value = $strategy->hydrate($value);
}
return $value;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator\Strategy;
/**
* @todo v3.0, add optional object/data to extract/hydrate.
*/
interface StrategyInterface
{
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @param object $object (optional) The original object for context.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value);
/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @param array $data (optional) The original data for context.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value);
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Hydrator;
interface StrategyEnabledInterface
{
/**
* Adds the given strategy under the given name.
*
* @param string $name The name of the strategy to register.
* @param Strategy\StrategyInterface $strategy The strategy to register.
* @return self
*/
public function addStrategy($name, Strategy\StrategyInterface $strategy);
/**
* Gets the strategy with the given name.
*
* @param string $name The name of the strategy to get.
* @return Strategy\StrategyInterface
*/
public function getStrategy($name);
/**
* Checks if the strategy with the given name exists.
*
* @param string $name The name of the strategy to check for.
* @return bool
*/
public function hasStrategy($name);
/**
* Removes the strategy with the given name.
*
* @param string $name The name of the strategy to remove.
* @return self
*/
public function removeStrategy($name);
}