Completed
Push — master ( e8cf0b...dd193e )
by Maxim
03:10
created

HandlersRunner::runStandardHandler()   B

Complexity

Conditions 5
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 1
nop 2
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is a part of "Axessors" library.
4
 *
5
 * @author <[email protected]>
6
 * @license GPL
7
 */
8
9
namespace NoOne4rever\Axessors;
10
11
use NoOne4rever\Axessors\Exceptions\OopError;
12
use NoOne4rever\Axessors\Exceptions\TypeError;
13
14
/**
15
 * Class HandlersSuit.
16
 * 
17
 * Processes Axessors handlers.
18
 * 
19
 * @package NoOne4rever\Axessors
20
 */
21
class HandlersRunner extends RunningSuit
22
{
23
    /**
24
     * Executes handlers defined in the Axessors comment.
25
     *
26
     * @param $value mixed value of the property
27
     * @return mixed new value of the property
28
     * @throws OopError if the property does not have one of the handlers defined in the Axessors comment
29
     */
30 43
    public function executeHandlers($value)
31
    {
32 43
        $handlers = $this->mode == RunningSuit::OUTPUT_MODE ? $this->propertyData->getOutputHandlers() : $this->propertyData->getInputHandlers();
33 43
        foreach ($handlers as $handler) {
34 11
            if (strpos($handler, '`') !== false) {
35 6
                $value = $this->executeInjectedString($handler, $value, false);
36
            } else {
37 6
                $value = $this->runStandardHandler($handler, $value);
38
            }
39
        }
40 39
        return $value;
41
    }
42
43
    /**
44
     * Runs Axessors handler.
45
     * 
46
     * @param string $handler handler name
47
     * @param mixed $value the value to process
48
     * @return mixed the result of handler execution
49
     * @throws TypeError if the called handler not found
50
     */
51 6
    private function runStandardHandler(string $handler, $value)
52
    {
53 6
        foreach ($this->propertyData->getTypeTree() as $type => $subType) {
54 6
            $reflection = new \ReflectionClass('\Axessors\Types\\' . is_int($type) ? $subType : $type);
55 6
            foreach ($reflection->getMethods() as $method) {
56 6
                if ($this->isCalledHandler($method, $handler, $reflection->name, $value)) {
57 6
                    return call_user_func([$reflection->name, $method->name], $value, false);
58
                }
59
            }
60
        }
61 2
        throw new TypeError("property {$this->class}::\${$this->propertyData->getName()} does not have handler \"$handler\"");
62
    }
63
64
    /**
65
     * Checks if the method can be called.
66
     * 
67
     * @param \ReflectionMethod $method method reflection
68
     * @return bool the result of the checkout
69
     */
70 6
    private function isMethodAccessible(\ReflectionMethod $method): bool
71
    {
72 6
        return $method->isPublic() && $method->isStatic() && !$method->isAbstract();
73
    }
74
75
    /**
76
     * Checks if the value match handler's type.
77
     * 
78
     * @param string $type type
79
     * @param mixed $value value
80
     * @return bool the result of the checkout
81
     */
82 6
    private function valueMatchType(string $type, $value): bool
83
    {
84 6
        return call_user_func([$type, 'is'], $value);
85
    }
86
87
    /**
88
     * Checks if the handler can be called.
89
     * 
90
     * @param \ReflectionMethod $method method reflection
91
     * @param string $handler handler name
92
     * @param string $type type
93
     * @param mixed $value value
94
     * @return bool the result of the checkout
95
     */
96 6
    private function isCalledHandler(\ReflectionMethod $method, string $handler, string $type, $value): bool 
97
    {
98 6
        return $this->isMethodAccessible($method) && $this->valueMatchType($type, $value) && "h_$handler" === $method->name;
99
    }
100
}