mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2025-02-23 01:29:25 +01:00
327 lines
8.7 KiB
PHP
327 lines
8.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @see https://github.com/laminas/laminas-validator for the canonical source repository
|
|
* @copyright https://github.com/laminas/laminas-validator/blob/master/COPYRIGHT.md
|
|
* @license https://github.com/laminas/laminas-validator/blob/master/LICENSE.md New BSD License
|
|
*/
|
|
|
|
namespace Laminas\Validator;
|
|
|
|
use Countable;
|
|
use Laminas\ServiceManager\ServiceManager;
|
|
use Laminas\Stdlib\PriorityQueue;
|
|
|
|
class ValidatorChain implements
|
|
Countable,
|
|
ValidatorInterface
|
|
{
|
|
/**
|
|
* Default priority at which validators are added
|
|
*/
|
|
const DEFAULT_PRIORITY = 1;
|
|
|
|
/**
|
|
* @var ValidatorPluginManager
|
|
*/
|
|
protected $plugins;
|
|
|
|
/**
|
|
* Validator chain
|
|
*
|
|
* @var PriorityQueue
|
|
*/
|
|
protected $validators;
|
|
|
|
/**
|
|
* Array of validation failure messages
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $messages = [];
|
|
|
|
/**
|
|
* Initialize validator chain
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->validators = new PriorityQueue();
|
|
}
|
|
|
|
/**
|
|
* Return the count of attached validators
|
|
*
|
|
* @return int
|
|
*/
|
|
public function count()
|
|
{
|
|
return count($this->validators);
|
|
}
|
|
|
|
/**
|
|
* Get plugin manager instance
|
|
*
|
|
* @return ValidatorPluginManager
|
|
*/
|
|
public function getPluginManager()
|
|
{
|
|
if (! $this->plugins) {
|
|
$this->setPluginManager(new ValidatorPluginManager(new ServiceManager));
|
|
}
|
|
return $this->plugins;
|
|
}
|
|
|
|
/**
|
|
* Set plugin manager instance
|
|
*
|
|
* @param ValidatorPluginManager $plugins Plugin manager
|
|
* @return $this
|
|
*/
|
|
public function setPluginManager(ValidatorPluginManager $plugins)
|
|
{
|
|
$this->plugins = $plugins;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a validator by name
|
|
*
|
|
* @param string $name Name of validator to return
|
|
* @param null|array $options Options to pass to validator constructor (if not already instantiated)
|
|
* @return ValidatorInterface
|
|
*/
|
|
public function plugin($name, array $options = null)
|
|
{
|
|
$plugins = $this->getPluginManager();
|
|
return $plugins->get($name, $options);
|
|
}
|
|
|
|
/**
|
|
* Attach a validator to the end of the chain
|
|
*
|
|
* If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain,
|
|
* if one exists, will not be executed.
|
|
*
|
|
* @param ValidatorInterface $validator
|
|
* @param bool $breakChainOnFailure
|
|
* @param int $priority Priority at which to enqueue validator; defaults to
|
|
* 1 (higher executes earlier)
|
|
*
|
|
* @throws Exception\InvalidArgumentException
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function attach(
|
|
ValidatorInterface $validator,
|
|
$breakChainOnFailure = false,
|
|
$priority = self::DEFAULT_PRIORITY
|
|
) {
|
|
$this->validators->insert(
|
|
[
|
|
'instance' => $validator,
|
|
'breakChainOnFailure' => (bool) $breakChainOnFailure,
|
|
],
|
|
$priority
|
|
);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Proxy to attach() to keep BC
|
|
*
|
|
* @deprecated Please use attach()
|
|
* @param ValidatorInterface $validator
|
|
* @param bool $breakChainOnFailure
|
|
* @param int $priority
|
|
* @return ValidatorChain Provides a fluent interface
|
|
*/
|
|
public function addValidator(
|
|
ValidatorInterface $validator,
|
|
$breakChainOnFailure = false,
|
|
$priority = self::DEFAULT_PRIORITY
|
|
) {
|
|
return $this->attach($validator, $breakChainOnFailure, $priority);
|
|
}
|
|
|
|
/**
|
|
* Adds a validator to the beginning of the chain
|
|
*
|
|
* If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain,
|
|
* if one exists, will not be executed.
|
|
*
|
|
* @param ValidatorInterface $validator
|
|
* @param bool $breakChainOnFailure
|
|
* @return $this Provides a fluent interface
|
|
*/
|
|
public function prependValidator(ValidatorInterface $validator, $breakChainOnFailure = false)
|
|
{
|
|
$priority = self::DEFAULT_PRIORITY;
|
|
|
|
if (! $this->validators->isEmpty()) {
|
|
$extractedNodes = $this->validators->toArray(PriorityQueue::EXTR_PRIORITY);
|
|
rsort($extractedNodes, SORT_NUMERIC);
|
|
$priority = $extractedNodes[0] + 1;
|
|
}
|
|
|
|
$this->validators->insert(
|
|
[
|
|
'instance' => $validator,
|
|
'breakChainOnFailure' => (bool) $breakChainOnFailure,
|
|
],
|
|
$priority
|
|
);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Use the plugin manager to add a validator by name
|
|
*
|
|
* @param string $name
|
|
* @param array $options
|
|
* @param bool $breakChainOnFailure
|
|
* @param int $priority
|
|
* @return $this
|
|
*/
|
|
public function attachByName($name, $options = [], $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY)
|
|
{
|
|
if (isset($options['break_chain_on_failure'])) {
|
|
$breakChainOnFailure = (bool) $options['break_chain_on_failure'];
|
|
}
|
|
|
|
if (isset($options['breakchainonfailure'])) {
|
|
$breakChainOnFailure = (bool) $options['breakchainonfailure'];
|
|
}
|
|
|
|
$this->attach($this->plugin($name, $options), $breakChainOnFailure, $priority);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Proxy to attachByName() to keep BC
|
|
*
|
|
* @deprecated Please use attachByName()
|
|
* @param string $name
|
|
* @param array $options
|
|
* @param bool $breakChainOnFailure
|
|
* @return ValidatorChain
|
|
*/
|
|
public function addByName($name, $options = [], $breakChainOnFailure = false)
|
|
{
|
|
return $this->attachByName($name, $options, $breakChainOnFailure);
|
|
}
|
|
|
|
/**
|
|
* Use the plugin manager to prepend a validator by name
|
|
*
|
|
* @param string $name
|
|
* @param array $options
|
|
* @param bool $breakChainOnFailure
|
|
* @return $this
|
|
*/
|
|
public function prependByName($name, $options = [], $breakChainOnFailure = false)
|
|
{
|
|
$validator = $this->plugin($name, $options);
|
|
$this->prependValidator($validator, $breakChainOnFailure);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns true if and only if $value passes all validations in the chain
|
|
*
|
|
* Validators are run in the order in which they were added to the chain (FIFO).
|
|
*
|
|
* @param mixed $value
|
|
* @param mixed $context Extra "context" to provide the validator
|
|
* @return bool
|
|
*/
|
|
public function isValid($value, $context = null)
|
|
{
|
|
$this->messages = [];
|
|
$result = true;
|
|
foreach ($this->validators as $element) {
|
|
$validator = $element['instance'];
|
|
if ($validator->isValid($value, $context)) {
|
|
continue;
|
|
}
|
|
$result = false;
|
|
$messages = $validator->getMessages();
|
|
$this->messages = array_replace_recursive($this->messages, $messages);
|
|
if ($element['breakChainOnFailure']) {
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Merge the validator chain with the one given in parameter
|
|
*
|
|
* @param ValidatorChain $validatorChain
|
|
* @return $this
|
|
*/
|
|
public function merge(ValidatorChain $validatorChain)
|
|
{
|
|
foreach ($validatorChain->validators->toArray(PriorityQueue::EXTR_BOTH) as $item) {
|
|
$this->attach($item['data']['instance'], $item['data']['breakChainOnFailure'], $item['priority']);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns array of validation failure messages
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getMessages()
|
|
{
|
|
return $this->messages;
|
|
}
|
|
|
|
/**
|
|
* Get all the validators
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getValidators()
|
|
{
|
|
return $this->validators->toArray(PriorityQueue::EXTR_DATA);
|
|
}
|
|
|
|
/**
|
|
* Invoke chain as command
|
|
*
|
|
* @param mixed $value
|
|
* @return bool
|
|
*/
|
|
public function __invoke($value)
|
|
{
|
|
return $this->isValid($value);
|
|
}
|
|
|
|
/**
|
|
* Deep clone handling
|
|
*/
|
|
public function __clone()
|
|
{
|
|
$this->validators = clone $this->validators;
|
|
}
|
|
|
|
/**
|
|
* Prepare validator chain for serialization
|
|
*
|
|
* Plugin manager (property 'plugins') cannot
|
|
* be serialized. On wakeup the property remains unset
|
|
* and next invocation to getPluginManager() sets
|
|
* the default plugin manager instance (ValidatorPluginManager).
|
|
*
|
|
* @return array
|
|
*/
|
|
public function __sleep()
|
|
{
|
|
return ['validators', 'messages'];
|
|
}
|
|
}
|