Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
15.62% |
5 / 32 |
CRAP | |
33.33% |
56 / 168 |
AbstractValidator | |
0.00% |
0 / 1 |
|
15.62% |
5 / 32 |
1880.67 | |
33.33% |
56 / 168 |
__construct($options = null) | |
0.00% |
0 / 1 |
5.73 | |
69.23% |
9 / 13 |
|||
getOption($option) | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 5 |
|||
getOptions() | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
setOptions($options = array()) | |
0.00% |
0 / 1 |
12.54 | |
70.59% |
12 / 17 |
|||
getMessages() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
__invoke($value) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
getMessageVariables() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
getMessageTemplates() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setMessage($messageString, $messageKey = null) | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 10 |
|||
setMessages(array $messages) | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 4 |
|||
__get($property) | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 17 |
|||
createMessage($messageKey, $value) | |
0.00% |
0 / 1 |
30.95 | |
45.16% |
14 / 31 |
|||
error($messageKey, $value = null) | |
0.00% |
0 / 1 |
3.33 | |
66.67% |
6 / 9 |
|||
getValue() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setValue($value) | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
setValueObscured($flag) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
isValueObscured() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setTranslator(Translator\TranslatorInterface $translator = null, $textDomain = null) | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
getTranslator() | |
0.00% |
0 / 1 |
3.04 | |
83.33% |
5 / 6 |
|||
hasTranslator() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setTranslatorTextDomain($textDomain = 'default') | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
getTranslatorTextDomain() | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
setDefaultTranslator( Translator\TranslatorInterface $translator = null, $textDomain = null ) | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
getDefaultTranslator() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
hasDefaultTranslator() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setDefaultTranslatorTextDomain($textDomain = 'default') | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
getDefaultTranslatorTextDomain() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setTranslatorEnabled($flag = true) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
isTranslatorEnabled() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getMessageLength() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setMessageLength($length = -1) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
translateMessage($messageKey, $message) | |
0.00% |
0 / 1 |
6.46 | |
27.27% |
3 / 11 |
<?php | |
/** | |
* Zend Framework (http://framework.zend.com/) | |
* | |
* @link http://github.com/zendframework/zf2 for the canonical source repository | |
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) | |
* @license http://framework.zend.com/license/new-bsd New BSD License | |
*/ | |
namespace Zend\Validator; | |
use Traversable; | |
use Zend\Stdlib\ArrayUtils; | |
abstract class AbstractValidator implements | |
Translator\TranslatorAwareInterface, | |
ValidatorInterface | |
{ | |
/** | |
* The value to be validated | |
* | |
* @var mixed | |
*/ | |
protected $value; | |
/** | |
* Default translation object for all validate objects | |
* @var Translator\TranslatorInterface | |
*/ | |
protected static $defaultTranslator; | |
/** | |
* Default text domain to be used with translator | |
* @var string | |
*/ | |
protected static $defaultTranslatorTextDomain = 'default'; | |
/** | |
* Limits the maximum returned length of a error message | |
* | |
* @var int | |
*/ | |
protected static $messageLength = -1; | |
protected $abstractOptions = array( | |
'messages' => array(), // Array of validation failure messages | |
'messageTemplates' => array(), // Array of validation failure message templates | |
'messageVariables' => array(), // Array of additional variables available for validation failure messages | |
'translator' => null, // Translation object to used -> Translator\TranslatorInterface | |
'translatorTextDomain' => null, // Translation text domain | |
'translatorEnabled' => true, // Is translation enabled? | |
'valueObscured' => false, // Flag indicating whether or not value should be obfuscated | |
// in error messages | |
); | |
/** | |
* Abstract constructor for all validators | |
* A validator should accept following parameters: | |
* - nothing f.e. Validator() | |
* - one or multiple scalar values f.e. Validator($first, $second, $third) | |
* - an array f.e. Validator(array($first => 'first', $second => 'second', $third => 'third')) | |
* - an instance of Traversable f.e. Validator($config_instance) | |
* | |
* @param array|Traversable $options | |
*/ | |
public function __construct($options = null) | |
{ | |
// The abstract constructor allows no scalar values | |
if ($options instanceof Traversable) { | |
$options = ArrayUtils::iteratorToArray($options); | |
} | |
if (isset($this->messageTemplates)) { | |
$this->abstractOptions['messageTemplates'] = $this->messageTemplates; | |
} | |
if (isset($this->messageVariables)) { | |
$this->abstractOptions['messageVariables'] = $this->messageVariables; | |
} | |
if (is_array($options)) { | |
$this->setOptions($options); | |
} | |
} | |
/** | |
* Returns an option | |
* | |
* @param string $option Option to be returned | |
* @return mixed Returned option | |
* @throws Exception\InvalidArgumentException | |
*/ | |
public function getOption($option) | |
{ | |
if (array_key_exists($option, $this->abstractOptions)) { | |
return $this->abstractOptions[$option]; | |
} | |
if (isset($this->options) && array_key_exists($option, $this->options)) { | |
return $this->options[$option]; | |
} | |
throw new Exception\InvalidArgumentException("Invalid option '$option'"); | |
} | |
/** | |
* Returns all available options | |
* | |
* @return array Array with all available options | |
*/ | |
public function getOptions() | |
{ | |
$result = $this->abstractOptions; | |
if (isset($this->options)) { | |
$result += $this->options; | |
} | |
return $result; | |
} | |
/** | |
* Sets one or multiple options | |
* | |
* @param array|Traversable $options Options to set | |
* @throws Exception\InvalidArgumentException If $options is not an array or Traversable | |
* @return AbstractValidator Provides fluid interface | |
*/ | |
public function setOptions($options = array()) | |
{ | |
if (!is_array($options) && !$options instanceof Traversable) { | |
throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable'); | |
} | |
foreach ($options as $name => $option) { | |
$fname = 'set' . ucfirst($name); | |
$fname2 = 'is' . ucfirst($name); | |
if (($name != 'setOptions') && method_exists($this, $name)) { | |
$this->{$name}($option); | |
} elseif (($fname != 'setOptions') && method_exists($this, $fname)) { | |
$this->{$fname}($option); | |
} elseif (method_exists($this, $fname2)) { | |
$this->{$fname2}($option); | |
} elseif (isset($this->options)) { | |
$this->options[$name] = $option; | |
} else { | |
$this->abstractOptions[$name] = $option; | |
} | |
} | |
return $this; | |
} | |
/** | |
* Returns array of validation failure messages | |
* | |
* @return array | |
*/ | |
public function getMessages() | |
{ | |
return array_unique($this->abstractOptions['messages']); | |
} | |
/** | |
* Invoke as command | |
* | |
* @param mixed $value | |
* @return bool | |
*/ | |
public function __invoke($value) | |
{ | |
return $this->isValid($value); | |
} | |
/** | |
* Returns an array of the names of variables that are used in constructing validation failure messages | |
* | |
* @return array | |
*/ | |
public function getMessageVariables() | |
{ | |
return array_keys($this->abstractOptions['messageVariables']); | |
} | |
/** | |
* Returns the message templates from the validator | |
* | |
* @return array | |
*/ | |
public function getMessageTemplates() | |
{ | |
return $this->abstractOptions['messageTemplates']; | |
} | |
/** | |
* Sets the validation failure message template for a particular key | |
* | |
* @param string $messageString | |
* @param string $messageKey OPTIONAL | |
* @return AbstractValidator Provides a fluent interface | |
* @throws Exception\InvalidArgumentException | |
*/ | |
public function setMessage($messageString, $messageKey = null) | |
{ | |
if ($messageKey === null) { | |
$keys = array_keys($this->abstractOptions['messageTemplates']); | |
foreach ($keys as $key) { | |
$this->setMessage($messageString, $key); | |
} | |
return $this; | |
} | |
if (!isset($this->abstractOptions['messageTemplates'][$messageKey])) { | |
throw new Exception\InvalidArgumentException("No message template exists for key '$messageKey'"); | |
} | |
$this->abstractOptions['messageTemplates'][$messageKey] = $messageString; | |
return $this; | |
} | |
/** | |
* Sets validation failure message templates given as an array, where the array keys are the message keys, | |
* and the array values are the message template strings. | |
* | |
* @param array $messages | |
* @return AbstractValidator | |
*/ | |
public function setMessages(array $messages) | |
{ | |
foreach ($messages as $key => $message) { | |
$this->setMessage($message, $key); | |
} | |
return $this; | |
} | |
/** | |
* Magic function returns the value of the requested property, if and only if it is the value or a | |
* message variable. | |
* | |
* @param string $property | |
* @return mixed | |
* @throws Exception\InvalidArgumentException | |
*/ | |
public function __get($property) | |
{ | |
if ($property == 'value') { | |
return $this->value; | |
} | |
if (array_key_exists($property, $this->abstractOptions['messageVariables'])) { | |
$result = $this->abstractOptions['messageVariables'][$property]; | |
if (is_array($result)) { | |
$result = $this->{key($result)}[current($result)]; | |
} else { | |
$result = $this->{$result}; | |
} | |
return $result; | |
} | |
if (isset($this->messageVariables) && array_key_exists($property, $this->messageVariables)) { | |
$result = $this->{$this->messageVariables[$property]}; | |
if (is_array($result)) { | |
$result = $this->{key($result)}[current($result)]; | |
} else { | |
$result = $this->{$result}; | |
} | |
return $result; | |
} | |
throw new Exception\InvalidArgumentException("No property exists by the name '$property'"); | |
} | |
/** | |
* Constructs and returns a validation failure message with the given message key and value. | |
* | |
* Returns null if and only if $messageKey does not correspond to an existing template. | |
* | |
* If a translator is available and a translation exists for $messageKey, | |
* the translation will be used. | |
* | |
* @param string $messageKey | |
* @param string|array|object $value | |
* @return string | |
*/ | |
protected function createMessage($messageKey, $value) | |
{ | |
if (!isset($this->abstractOptions['messageTemplates'][$messageKey])) { | |
return null; | |
} | |
$message = $this->abstractOptions['messageTemplates'][$messageKey]; | |
$message = $this->translateMessage($messageKey, $message); | |
if (is_object($value) && | |
!in_array('__toString', get_class_methods($value)) | |
) { | |
$value = get_class($value) . ' object'; | |
} elseif (is_array($value)) { | |
$value = var_export($value, 1); | |
} else { | |
$value = (string) $value; | |
} | |
if ($this->isValueObscured()) { | |
$value = str_repeat('*', strlen($value)); | |
} | |
$message = str_replace('%value%', (string) $value, $message); | |
foreach ($this->abstractOptions['messageVariables'] as $ident => $property) { | |
if (is_array($property)) { | |
$value = $this->{key($property)}[current($property)]; | |
if (is_array($value)) { | |
$value = '[' . implode(', ', $value) . ']'; | |
} | |
} else { | |
$value = $this->$property; | |
} | |
$message = str_replace("%$ident%", (string) $value, $message); | |
} | |
$length = self::getMessageLength(); | |
if (($length > -1) && (strlen($message) > $length)) { | |
$message = substr($message, 0, ($length - 3)) . '...'; | |
} | |
return $message; | |
} | |
/** | |
* @param string $messageKey | |
* @param string $value OPTIONAL | |
* @return void | |
*/ | |
protected function error($messageKey, $value = null) | |
{ | |
if ($messageKey === null) { | |
$keys = array_keys($this->abstractOptions['messageTemplates']); | |
$messageKey = current($keys); | |
} | |
if ($value === null) { | |
$value = $this->value; | |
} | |
$this->abstractOptions['messages'][$messageKey] = $this->createMessage($messageKey, $value); | |
} | |
/** | |
* Returns the validation value | |
* | |
* @return mixed Value to be validated | |
*/ | |
protected function getValue() | |
{ | |
return $this->value; | |
} | |
/** | |
* Sets the value to be validated and clears the messages and errors arrays | |
* | |
* @param mixed $value | |
* @return void | |
*/ | |
protected function setValue($value) | |
{ | |
$this->value = $value; | |
$this->abstractOptions['messages'] = array(); | |
} | |
/** | |
* Set flag indicating whether or not value should be obfuscated in messages | |
* | |
* @param bool $flag | |
* @return AbstractValidator | |
*/ | |
public function setValueObscured($flag) | |
{ | |
$this->abstractOptions['valueObscured'] = (bool) $flag; | |
return $this; | |
} | |
/** | |
* Retrieve flag indicating whether or not value should be obfuscated in | |
* messages | |
* | |
* @return bool | |
*/ | |
public function isValueObscured() | |
{ | |
return $this->abstractOptions['valueObscured']; | |
} | |
/** | |
* Set translation object | |
* | |
* @param Translator\TranslatorInterface|null $translator | |
* @param string $textDomain (optional) | |
* @return AbstractValidator | |
* @throws Exception\InvalidArgumentException | |
*/ | |
public function setTranslator(Translator\TranslatorInterface $translator = null, $textDomain = null) | |
{ | |
$this->abstractOptions['translator'] = $translator; | |
if (null !== $textDomain) { | |
$this->setTranslatorTextDomain($textDomain); | |
} | |
return $this; | |
} | |
/** | |
* Return translation object | |
* | |
* @return Translator\TranslatorInterface|null | |
*/ | |
public function getTranslator() | |
{ | |
if (! $this->isTranslatorEnabled()) { | |
return null; | |
} | |
if (null === $this->abstractOptions['translator']) { | |
$this->abstractOptions['translator'] = self::getDefaultTranslator(); | |
} | |
return $this->abstractOptions['translator']; | |
} | |
/** | |
* Does this validator have its own specific translator? | |
* | |
* @return bool | |
*/ | |
public function hasTranslator() | |
{ | |
return (bool) $this->abstractOptions['translator']; | |
} | |
/** | |
* Set translation text domain | |
* | |
* @param string $textDomain | |
* @return AbstractValidator | |
*/ | |
public function setTranslatorTextDomain($textDomain = 'default') | |
{ | |
$this->abstractOptions['translatorTextDomain'] = $textDomain; | |
return $this; | |
} | |
/** | |
* Return the translation text domain | |
* | |
* @return string | |
*/ | |
public function getTranslatorTextDomain() | |
{ | |
if (null === $this->abstractOptions['translatorTextDomain']) { | |
$this->abstractOptions['translatorTextDomain'] = | |
self::getDefaultTranslatorTextDomain(); | |
} | |
return $this->abstractOptions['translatorTextDomain']; | |
} | |
/** | |
* Set default translation object for all validate objects | |
* | |
* @param Translator\TranslatorInterface|null $translator | |
* @param string $textDomain (optional) | |
* @return void | |
* @throws Exception\InvalidArgumentException | |
*/ | |
public static function setDefaultTranslator( | |
Translator\TranslatorInterface $translator = null, $textDomain = null | |
) | |
{ | |
static::$defaultTranslator = $translator; | |
if (null !== $textDomain) { | |
self::setDefaultTranslatorTextDomain($textDomain); | |
} | |
} | |
/** | |
* Get default translation object for all validate objects | |
* | |
* @return Translator\TranslatorInterface|null | |
*/ | |
public static function getDefaultTranslator() | |
{ | |
return static::$defaultTranslator; | |
} | |
/** | |
* Is there a default translation object set? | |
* | |
* @return bool | |
*/ | |
public static function hasDefaultTranslator() | |
{ | |
return (bool) static::$defaultTranslator; | |
} | |
/** | |
* Set default translation text domain for all validate objects | |
* | |
* @param string $textDomain | |
* @return void | |
*/ | |
public static function setDefaultTranslatorTextDomain($textDomain = 'default') | |
{ | |
static::$defaultTranslatorTextDomain = $textDomain; | |
} | |
/** | |
* Get default translation text domain for all validate objects | |
* | |
* @return string | |
*/ | |
public static function getDefaultTranslatorTextDomain() | |
{ | |
return static::$defaultTranslatorTextDomain; | |
} | |
/** | |
* Indicate whether or not translation should be enabled | |
* | |
* @param bool $flag | |
* @return AbstractValidator | |
*/ | |
public function setTranslatorEnabled($flag = true) | |
{ | |
$this->abstractOptions['translatorEnabled'] = (bool) $flag; | |
return $this; | |
} | |
/** | |
* Is translation enabled? | |
* | |
* @return bool | |
*/ | |
public function isTranslatorEnabled() | |
{ | |
return $this->abstractOptions['translatorEnabled']; | |
} | |
/** | |
* Returns the maximum allowed message length | |
* | |
* @return int | |
*/ | |
public static function getMessageLength() | |
{ | |
return static::$messageLength; | |
} | |
/** | |
* Sets the maximum allowed message length | |
* | |
* @param int $length | |
*/ | |
public static function setMessageLength($length = -1) | |
{ | |
static::$messageLength = $length; | |
} | |
/** | |
* Translate a validation message | |
* | |
* @param string $messageKey | |
* @param string $message | |
* @return string | |
*/ | |
protected function translateMessage($messageKey, $message) | |
{ | |
$translator = $this->getTranslator(); | |
if (!$translator) { | |
return $message; | |
} | |
$translated = $translator->translate( | |
$messageKey, $this->getTranslatorTextDomain() | |
); | |
if ($translated !== $messageKey) { | |
return $translated; | |
} | |
return $translator->translate( | |
$message, $this->getTranslatorTextDomain() | |
); | |
} | |
} |