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

ClosureWrapper   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 55
ccs 0
cts 15
cp 0
rs 10
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 4
A publish() 0 3 1
A getClosureParameters() 0 4 1
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