Completed
Push — master ( f70b57...5f6191 )
by Changwan
06:48
created

TesterLoader::addTester()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
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 TesterLoader
31
{
32
    /** @var string[] */
33
    protected $testers;
34
35
    /** @var \Wandu\Validator\Contracts\Tester[] */
36
    protected $caches = [];
37
38 37
    public function __construct(array $testers = [])
39
    {
40 37
        $this->testers = $testers + [
41 37
                '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
                'int' => IntegerTester::class,
58
                'integer' => IntegerTester::class,
59
                'length_max' => LengthMaxTester::class,
60
                'length_min' => LengthMinTester::class,
61
                'less_than' => LessThanTester::class,
62
                'less_than_or_equal' => LessThanOrEqualTester::class,
63
                'lt' => LessThanTester::class,
64
                'lte' => LessThanOrEqualTester::class,
65
                'max' => MaxTester::class,
66
                '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 37
    }
74
75
    /**
76
     * @param string $name
77
     * @param string $testClassName
78
     */
79
    public function addTester($name, $testClassName)
80
    {
81
        $this->testers[$name] = $testClassName;
82
    }
83
    
84
    /**
85
     * @param string $tester
86
     * @return \Wandu\Validator\Contracts\Tester
87
     */
88 22
    public function load(string $tester): Tester
89
    {
90 22
        list($name, $arguments) = $this->getMethodAndParams($tester);
91 22
        if (!array_key_exists($tester, $this->caches)) {
92 22
            $this->caches[$tester] = $this->create($name, $arguments);
93
        }
94 22
        return $this->caches[$tester];
95
    }
96
97
    /**
98
     * @param string $tester
99
     * @param array $arguments
100
     * @return \Wandu\Validator\Contracts\Tester
101
     */
102 35
    public function create(string $tester, array $arguments = []): Tester
103
    {
104 35
        $className = $this->getClassName($tester);
105 35
        return new $className(...$arguments);
106
    }
107
    
108
    /**
109
     * @param string $pattern
110
     * @return array
111
     */
112 22
    protected function getMethodAndParams($pattern)
113
    {
114 22
        $pattern = trim($pattern);
115 22
        if (false === $pivot = strpos($pattern, ':')) {
116 9
            return [$pattern, []]; // "simple"
117
        }
118 17
        $method = substr($pattern, 0, $pivot);
119 17
        preg_match_all('/\/[^\/]*\/|[^,]+/', substr($pattern, $pivot + 1), $matches);
120 17
        $params = array_reduce(
121 17
            $matches[0],
122 17
            function ($carry, $value) {
123 17
                $value = trim($value);
124 17
                if ($value) {
125 17
                    $carry[] = $value;
126
                }
127 17
                return $carry;
128 17
            },
129 17
            []
130
        );
131 17
        return [$method, $params];
132
    }
133
134
    /**
135
     * @param string $name
136
     * @return string
137
     */
138 35
    protected function getClassName($name)
139
    {
140 35
        if (isset($this->testers[$name])) {
141 35
            $className = $this->testers[$name];
142 35
            if (class_exists($className)) {
143 35
                return $className;
144
            }
145
        }
146
        throw new TesterNotFoundException($name);
147
    }
148
}
149