Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
Validator
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
7 / 7
19
100.00% covered (success)
100.00%
1 / 1
 getValidator
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 fromString
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 __callStatic
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __invoke
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 registerNamespace
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 resetNamespaces
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getError
n/a
0 / 0
n/a
0 / 0
1
 getInverseError
n/a
0 / 0
n/a
0 / 0
1
1<?php
2
3namespace Verja;
4
5use Verja\Exception\ValidatorNotFound;
6use Verja\Validator\Not;
7
8/**
9 * Class Validator
10 *
11 * @package Verja
12 * @author  Thomas Flori <thflori@gmail.com>
13 *
14 * @method static Validator\After after($dateTime)
15 * @method static Validator\Alpha alpha(bool $allowSpaces = false)
16 * @method static Validator\AlphaNumeric alphaNumeric(bool $allowSpaces = false)
17 * @method static Validator\Before before($dateTime)
18 * @method static Validator\Boolean boolean(array $stringTrue = [], array $stringFalse = [], $overwrite = false)
19 * @method static Validator\Between between($min = null, $max = null)
20 * @method static Validator\Callback callback(\Closure $callback)
21 * @method static Validator\Contains contains(string $subString)
22 * @method static Validator\CreditCard creditCard(string $subString)
23 * @method static Validator\DateTime dateTime(string $format = null, bool $strict = false)
24 * @method static Validator\EmailAddress emailAddress()
25 * @method static Validator\Equals equals(string $opposite, bool $jsonEncode = true)
26 * @method static Validator\InArray inArray($array)
27 * @method static Validator\Integer integer()
28 * @method static Validator\IpAddress ipAddress(string $version = 'any', string $range = 'any')
29 * @method static Validator\IsArray isArray(string $type)
30 * @method static Validator\Not not($validator)
31 * @method static Validator\NotEmpty notEmpty()
32 * @method static Validator\Numeric numeric(string $decimalPoint = '.')
33 * @method static Validator\PregMatch pregMatch(string $pattern)
34 * @method static Validator\Slug slug()
35 * @method static Validator\StrLen strLen(int $min, int $max = 0)
36 * @method static Validator\Truthful truthful()
37 * @method static Validator\Url url(string $coverage = 'complete', $schemes = ['https', 'http', 'ftp'])
38 */
39abstract class Validator implements ValidatorInterface
40{
41    use WithAssignedField;
42
43    /** @var string[] */
44    protected static $namespaces = [ '\\Verja\\Validator' ];
45
46    /** @var array */
47    protected $error;
48
49    /**
50     * Get a validator instance
51     *
52     * @param string|callable|ValidatorInterface $validator
53     * @return ValidatorInterface
54     * @throws ValidatorNotFound
55     */
56    public static function getValidator($validator)
57    {
58        if (is_string($validator)) {
59            $validator = static::fromString($validator);
60        } elseif (is_callable($validator) && !$validator instanceof ValidatorInterface) {
61            $validator = new Validator\Callback($validator);
62        }
63
64        if (!$validator instanceof ValidatorInterface) {
65            throw new \InvalidArgumentException('$validator has to be an instance of ValidatorInterface');
66        }
67
68        return $validator;
69    }
70
71    /**
72     * Create a Validator from $str
73     *
74     * This method uses Parser::parseClassNameWIthParameters. This method has some limitations for parameters - look
75     * at it's description to learn more.
76     *
77     * @param string $definition
78     * @return ValidatorInterface
79     * @see Parser::parseClassNameWithParameters() to learn how to pass parameters
80     * @throws ValidatorNotFound
81     */
82    public static function fromString(string $definition): ValidatorInterface
83    {
84        if (strlen($definition) > 0 && $definition[0] === '!') {
85            return new Not(substr($definition, 1));
86        }
87
88        return static::create(...Parser::parseClassNameWithParameters($definition));
89    }
90
91    /**
92     * Create a validator dynamically
93     *
94     * @param string $name
95     * @param array  $arguments
96     * @return ValidatorInterface
97     * @throws ValidatorNotFound
98     */
99    public static function __callStatic($name, array $arguments)
100    {
101        return static::create(ucfirst($name), $arguments);
102    }
103
104    /**
105     * Call the validator is an alias for validate
106     *
107     * @param mixed $value
108     * @param array $context
109     * @return bool
110     */
111    public function __invoke($value, array $context = []): bool
112    {
113        return $this->validate($value, $context);
114    }
115
116    /**
117     * Create a validator dynamically
118     *
119     * @param string $shortName
120     * @param array  $parameters
121     * @return ValidatorInterface
122     * @throws ValidatorNotFound
123     */
124    public static function create(string $shortName, array $parameters = []): ValidatorInterface
125    {
126        foreach (self::$namespaces as $namespace) {
127            $class = $namespace . '\\' . $shortName;
128            if (!class_exists($class)) {
129                continue;
130            }
131            $validator = new $class(...$parameters);
132            if (!$validator instanceof ValidatorInterface) {
133                continue;
134            }
135            return $validator;
136        }
137
138        throw new ValidatorNotFound($shortName);
139    }
140
141    /**
142     * Register an additional namespace
143     *
144     * @param string $namespace
145     */
146    public static function registerNamespace(string $namespace)
147    {
148        array_unshift(self::$namespaces, $namespace);
149
150        // Untestable - required to reduce performance impact
151        // @codeCoverageIgnoreStart
152        if (count(self::$namespaces) > 2) {
153            self::$namespaces = array_unique(self::$namespaces);
154        }
155        // @codeCoverageIgnoreEnd
156    }
157
158    /**
159     * Reset namespaces to defaults
160     */
161    public static function resetNamespaces()
162    {
163        self::$namespaces = [ '\\Verja\\Validator' ];
164    }
165
166    /**
167     * {@inheritdoc}
168     * @codeCoverageIgnore trivial
169     */
170    public function getError()
171    {
172        return $this->error;
173    }
174
175    /**
176     * The inverse error is not required to implement
177     *
178     * @param mixed $value
179     * @return null
180     * @codeCoverageIgnore trivial
181     */
182    public function getInverseError($value)
183    {
184        return null;
185    }
186}