Completed
Push — master ( 3309bb...059e5b )
by Changwan
02:58
created

TesterFactory::getClassName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 10
ccs 5
cts 6
cp 0.8333
crap 3.0416
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
35
    /** @var \Wandu\Validator\Contracts\Tester[] */
36
    protected $caches = [];
37
38 34
    public function __construct(array $testers = [])
39
    {
40 34
        $this->testers = $testers + [
41 34
                '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 34
    }
74
    
75
    /**
76
     * @param string $tester
77
     * @param array $arguments
78
     * @return \Wandu\Validator\Contracts\Tester
79
     */
80 32
    public function create(string $tester, array $arguments = []): Tester
81
    {
82 32
        $className = $this->getClassName($tester);
83 32
        return new $className(...$arguments);
84
    }
85
    
86
    /**
87
     * @param string $tester
88
     * @return \Wandu\Validator\Contracts\Tester
89
     */
90 20
    public function parse(string $tester): Tester
91
    {
92 20
        list($name, $arguments) = $this->getMethodAndParams($tester);
93 20
        if (!array_key_exists($tester, $this->caches)) {
94 20
            $this->caches[$tester] = $this->create($name, $arguments);
95
        }
96 20
        return $this->caches[$tester];
97
    }
98
99
    /**
100
     * @param string $pattern
101
     * @return array
102
     */
103 20
    protected function getMethodAndParams($pattern)
104
    {
105 20
        $pattern = trim($pattern);
106 20
        if (false === $pivot = strpos($pattern, ':')) {
107 7
            return [$pattern, []]; // "simple"
108
        }
109 16
        $method = substr($pattern, 0, $pivot);
110 16
        preg_match_all('/\/[^\/]*\/|[^,]+/', substr($pattern, $pivot + 1), $matches);
111 16
        $params = array_reduce(
112 16
            $matches[0],
113 16
            function ($carry, $value) {
114 16
                $value = trim($value);
115 16
                if ($value) {
116 16
                    $carry[] = $value;
117
                }
118 16
                return $carry;
119 16
            },
120 16
            []
121
        );
122 16
        return [$method, $params];
123
    }
124
125
    /**
126
     * @param string $name
127
     * @return string
128
     */
129 32
    protected function getClassName($name)
130
    {
131 32
        if (isset($this->testers[$name])) {
132 32
            $className = $this->testers[$name];
133 32
            if (class_exists($className)) {
134 32
                return $className;
135
            }
136
        }
137
        throw new TesterNotFoundException($name);
138
    }
139
}
140