Completed
Push — master ( cbad56...217662 )
by Pierre
03:21
created

ClosureWrapper::getArgTypeName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 6
rs 10
1
<?php
2
3
namespace App\Component\Pubsub;
4
5
use Closure;
6
use Exception;
7
use ReflectionFunction;
8
use ReflectionParameter;
9
use App\Component\Pubsub\EventInterface;
10
11
/**
12
 * ClosureWrapper
13
 * 
14
 * is a mediator pattern to let closure to comply ListenerInterface.
15
 */
16
class ClosureWrapper extends ListenerAbstract implements ListenerInterface
17
{
18
    const PHP_VER_REF = '7.1';
19
    /**
20
     * listener as closure
21
     *
22
     * @var Closure
23
     */
24
    protected $closure;
25
26
    /**
27
     * instanciate
28
     *
29
     * @param Closure $closure
30
     */
31
    public function __construct(Closure $closure)
32
    {
33
        $params = $this->getClosureParameters($closure);
34
        if (count($params) === 0) {
35
            throw new Exception(self::ERR_CLOSURE_ARG_MISSING);
36
        }
37
        if ($this->getArgTypeName($params[0]) !== EventInterface::class) {
38
            throw new Exception(self::ERR_CLOSURE_ARG_INVALID);
39
        }
40
        $this->closure = $closure;
41
    }
42
43
    /**
44
     * publish
45
     *
46
     * @param EventInterface $event
47
     * @return void
48
     */
49
    public function publish(EventInterface $event)
50
    {
51
        call_user_func($this->closure, $event);
52
    }
53
54
    /**
55
     * return an array of reflexion parameter
56
     *
57
     * @see https://www.php.net/manual/fr/class.reflectionparameter.php
58
     *
59
     * @param Closure $closure
60
     * @return ReflectionParameter[]
61
     */
62
    protected function getClosureParameters(Closure $closure): array
63
    {
64
        $reflection = new ReflectionFunction($closure);
65
        return $reflection->getParameters();
66
    }
67
68
    /**
69
     * return type name for a ReflectionParameter arg
70
     *
71
     * @param ReflectionParameter $arg
72
     * @return string
73
     */
74
    protected function getArgTypeName(ReflectionParameter $arg): string
75
    {
76
        return (version_compare(phpversion(), self::PHP_VER_REF, '<'))
77
            ? (string) $arg->getType()
78
            : $arg->getType()->getName();
79
    }
80
}
81