Completed
Push — master ( 217662...7873a5 )
by Pierre
03:17
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 4
    public function __construct(Closure $closure)
32
    {
33 4
        $params = $this->getClosureParameters($closure);
34 4
        if (count($params) === 0) {
35 1
            throw new Exception(self::ERR_CLOSURE_ARG_MISSING);
36
        }
37 4
        if ($this->getArgTypeName($params[0]) !== EventInterface::class) {
38 1
            throw new Exception(self::ERR_CLOSURE_ARG_INVALID);
39
        }
40 4
        $this->closure = $closure;
41
    }
42
43
    /**
44
     * publish
45
     *
46
     * @param EventInterface $event
47
     * @return void
48
     */
49 1
    public function publish(EventInterface $event)
50
    {
51 1
        call_user_func($this->closure, $event);
52
    }
53
54
    /**
55
     * return an array of reflexion parameter
56
     *
57
     * @param Closure $closure
58
     * @return ReflectionParameter[]
59
     */
60
    protected function getClosureParameters(Closure $closure): array
61
    {
62
        $reflection = new ReflectionFunction($closure);
63
        return $reflection->getParameters();
64
    }
65
66
    /**
67
     * return type name for a ReflectionParameter arg
68
     *
69
     * @see https://www.php.net/manual/fr/class.reflectionparameter.php
70
     * @param ReflectionParameter $arg
71
     * @return string
72
     */
73
    protected function getArgTypeName(ReflectionParameter $arg): string
74
    {
75
        return (version_compare(phpversion(), self::PHP_VER_REF, '<'))
76
            ? (string) $arg->getType()
77
            : $arg->getType()->getName();
78
    }
79
}
80