ClosureWrapper::getClosureParameters()   A
last analyzed

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