Completed
Push — master ( 0d5c20...3309bb )
by Changwan
09:19
created

TesterFactory::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Validator;
3
4
use Wandu\Validator\Contracts\Tester;
5
use Wandu\Validator\Exception\TesterNotFoundException;
6
use Wandu\Validator\Testers\AfterTester;
7
use Wandu\Validator\Testers\EqualToTester;
8
use Wandu\Validator\Testers\GreaterThanOrEqualTester;
9
use Wandu\Validator\Testers\GreaterThanTester;
10
use Wandu\Validator\Testers\AlwaysFalseTester;
11
use Wandu\Validator\Testers\AlwaysTrueTester;
12
use Wandu\Validator\Testers\BeforeTester;
13
use Wandu\Validator\Testers\BooleanTester;
14
use Wandu\Validator\Testers\EmailTester;
15
use Wandu\Validator\Testers\FloatTester;
16
use Wandu\Validator\Testers\IntegerableTester;
17
use Wandu\Validator\Testers\IntegerTester;
18
use Wandu\Validator\Testers\LengthMaxTester;
19
use Wandu\Validator\Testers\LengthMinTester;
20
use Wandu\Validator\Testers\LessThanOrEqualTester;
21
use Wandu\Validator\Testers\LessThanTester;
22
use Wandu\Validator\Testers\MaxTester;
23
use Wandu\Validator\Testers\MinTester;
24
use Wandu\Validator\Testers\NumericTester;
25
use Wandu\Validator\Testers\PrintableTester;
26
use Wandu\Validator\Testers\RegExpTester;
27
use Wandu\Validator\Testers\StringableTester;
28
use Wandu\Validator\Testers\StringTester;
29
30
class TesterFactory
31
{
32
    /** @var string[] */
33
    protected $testers;
34 5
35
    /** @var \Wandu\Validator\Contracts\Tester[] */
36 5
    protected $caches = [];
37 5
38
    public function __construct(array $testers = [])
39
    {
40
        $this->testers = $testers + [
41
                'after' => AfterTester::class,
42
                'always_false' => AlwaysFalseTester::class,
43
                'always_true' => AlwaysTrueTester::class,
44
                'before' => BeforeTester::class,
45
                'bool' => BooleanTester::class,
46
                'boolean' => BooleanTester::class,
47
                'email' => EmailTester::class,
48
                'equal_to' => EqualToTester::class,
49
                'eq' => EqualToTester::class,
50
                'float' => FloatTester::class,
51
                'floatable' => NumericTester::class,
52
                'greater_than' => GreaterThanTester::class,
53
                'greater_than_or_equal' => GreaterThanOrEqualTester::class,
54
                'gt' => GreaterThanTester::class,
55
                'gte' => GreaterThanOrEqualTester::class,
56
                'integerable' => IntegerableTester::class,
57 5
                'int' => IntegerTester::class,
58
                'integer' => IntegerTester::class,
59
                'length_max' => LengthMaxTester::class,
60
                'length_min' => LengthMinTester::class,
61
                'less_than' => LessThanTester::class,
62 4
                'less_than_or_equal' => LessThanOrEqualTester::class,
63
                'lt' => LessThanTester::class,
64 4
                'lte' => LessThanOrEqualTester::class,
65 4
                'max' => MaxTester::class,
66 4
                'min' => MinTester::class,
67
                'numeric' => NumericTester::class,
68
                'printable' => PrintableTester::class,
69
                'regexp' => RegExpTester::class,
70
                'stringable' => StringableTester::class,
71
                'string' => StringTester::class,
72
            ];
73
    }
74 27
    
75
    /**
76 27
     * @param string $tester
77 2
     * @param array $arguments
78 2
     * @return \Wandu\Validator\Contracts\Tester
79
     */
80 25
    public function create(string $tester, array $arguments = []): Tester
81 25
    {
82 24
        $className = $this->getClassName($tester);
83 24
        return new $className(...$arguments);
84
    }
85 25
    
86
    /**
87
     * @param string $tester
88
     * @return \Wandu\Validator\Contracts\Tester
89
     */
90
    public function parse(string $tester): Tester
91
    {
92 25
        list($name, $arguments) = $this->getMethodAndParams($tester);
93
        if (!array_key_exists($tester, $this->caches)) {
94 25
            $this->caches[$tester] = $this->create($name, $arguments);
95 25
        }
96 19
        return $this->caches[$tester];
97
    }
98 9
99 9
    /**
100 9
     * @param string $pattern
101 9
     * @return array
102 9
     */
103 9
    protected function getMethodAndParams($pattern)
104 9
    {
105 9
        $pattern = trim($pattern);
106
        if (false === $pivot = strpos($pattern, ':')) {
107 9
            return [$pattern, []]; // "simple"
108 9
        }
109 9
        $method = substr($pattern, 0, $pivot);
110
        preg_match_all('/\/[^\/]*\/|[^,]+/', substr($pattern, $pivot + 1), $matches);
111 9
        $params = array_reduce(
112
            $matches[0],
113
            function ($carry, $value) {
114
                $value = trim($value);
115
                if ($value) {
116
                    $carry[] = $value;
117
                }
118 26
                return $carry;
119
            },
120 26
            []
121 26
        );
122 26
        return [$method, $params];
123 26
    }
124
125
    /**
126
     * @param string $name
127
     * @return string
128
     */
129
    protected function getClassName($name)
130
    {
131
        if (isset($this->testers[$name])) {
132
            $className = $this->testers[$name];
133
            if (class_exists($className)) {
134
                return $className;
135
            }
136
        }
137
        throw new TesterNotFoundException($name);
138
    }
139
}
140