Completed
Push — master ( 7873a5...9045a1 )
by Pierre
03:22
created

ClosureWrapper::getClosureParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 1
b 0
f 0
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 6
    public function __construct(Closure $closure)
32
    {
33 6
        $params = $this->getClosureParameters($closure);
34 6
        if (count($params) === 0) {
35 1
            throw new Exception(self::ERR_CLOSURE_ARG_MISSING);
36
        }
37 6
        if ($this->getArgTypeName($params[0]) !== EventInterface::class) {
38 1
            throw new Exception(self::ERR_CLOSURE_ARG_INVALID);
39
        }
40 6
        $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 2
    protected function getClosureParameters(Closure $closure): array
61
    {
62 2
        $reflection = new ReflectionFunction($closure);
63 2
        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 1
    protected function getArgTypeName(ReflectionParameter $arg): string
74
    {
75 1
        return (version_compare(phpversion(), self::PHP_VER_REF, '<'))
76
            ? (string) $arg->getType()
77 1
            : $arg->getType()->getName();
78
    }
79
}
80