Completed
Push — master ( 39a9ed...cbad56 )
by Pierre
03:38
created

ClosureWrapper::__construct()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 13
ccs 0
cts 10
cp 0
crap 20
rs 9.9666
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
class ClosureWrapper extends ListenerAbstract implements ListenerInterface
12
{
13
    const ERR_CLOSURE_ARG_MISSING = 'Listener closure required at least one Event argument';
14
    const ERR_CLOSURE_ARG_INVALID = 'Listener closure arg type should comply EventInterface';
15
16
    /**
17
     * listener as closure
18
     *
19
     * @var Closure
20
     */
21
    protected $closure;
22
23
    /**
24
     * instanciate
25
     *
26
     * @param Closure $closure
27
     */
28
    public function __construct(Closure $closure)
29
    {
30
        $params = $this->getClosureParameters($closure);
31
        if (count($params) === 0) {
32
            throw new Exception(self::ERR_CLOSURE_ARG_MISSING);
33
        }
34
        $argTypeName = (version_compare(phpversion(), '7.1', '<'))
35
            ? (string) $params[0]->getType()
36
            : $params[0]->getType()->getName();
37
        if ($argTypeName !== 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