Passed
Push — master ( cad3b0...819e05 )
by Maxim
02:58
created

HandlersSuit::isCalledHandler()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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