Callables::attachAll()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EngineWorks\Templates;
6
7
use Countable;
8
9
class Callables implements Countable
10
{
11
    /**
12
     * @var array<string, callable>
13
     */
14
    private $map = [];
15
16
    /**
17
     * Add a function callable to the collection
18
     */
19 12
    public function add(string $name, callable $callable): void
20
    {
21 12
        $this->map[$name] = $callable;
22
    }
23
24
    /**
25
     * Return a callable based on the string name
26
     * If the name is not registered then return NULL
27
     */
28 3
    public function get(string $name): ?callable
29
    {
30 3
        return $this->map[$name] ?? null;
31
    }
32
33
    /**
34
     * Return TRUE if the name is registered
35
     */
36 4
    public function exists(string $name): bool
37
    {
38 4
        return isset($this->map[$name]);
39
    }
40
41
    /**
42
     * Remove a registered name from the collection
43
     */
44 2
    public function remove(string $name): void
45
    {
46 2
        unset($this->map[$name]);
47
    }
48
49
    /**
50
     * Call a function by name
51
     *
52
     * @param array<mixed> $arguments
53
     */
54 2
    public function call(string $name, array $arguments): string
55
    {
56
        /** @var callable():string|null $callable */
57 2
        $callable = $this->get($name);
58 2
        if (null === $callable) {
0 ignored issues
show
introduced by
The condition null === $callable is always false.
Loading history...
59
            return '';
60
        }
61
62 2
        $return = call_user_func_array($callable, $arguments);
63
64 2
        if (is_object($return) && is_callable([$return, '__toString'])) {
65
            $return = (string) $return;
66 2
        } elseif (is_scalar($return)) {
67 2
            $return = (string) $return;
68
        }
69
70 2
        return is_string($return) ? $return : '';
71
    }
72
73
    /**
74
     * Return the names of the registered functions
75
     *
76
     * @return string[]
77
     */
78 4
    public function names(): array
79
    {
80 4
        return array_keys($this->map);
81
    }
82
83
    /**
84
     * Attach an array of plugins. Is a shortcut to call several times to attatch method
85
     * If an element of the array is not a plugin then the element is discarded without notice
86
     *
87
     * @param Plugin[] $plugins
88
     */
89 1
    public function attachAll(array $plugins): void
90
    {
91 1
        $this->attach(...$plugins);
92
    }
93
94
    /**
95
     * Attach all the functions offered by the plugin
96
     *
97
     * @param Plugin ...$plugins
98
     */
99 2
    public function attach(Plugin ...$plugins): void
100
    {
101 2
        foreach ($plugins as $plugin) {
102 2
            $this->attachPlugin($plugin);
103
        }
104
    }
105
106
    /**
107
     * Attach all the functions offered by the plugin
108
     *
109
     * @param Plugin $plugin
110
     */
111 2
    public function attachPlugin(Plugin $plugin): void
112
    {
113 2
        foreach ($plugin->getCallablesTable() as $name => $methodName) {
114
            /** @var callable():string $callable */
115 2
            $callable = [$plugin, $methodName];
116 2
            $this->add($name, $callable);
117
        }
118
    }
119
120
    /**
121
     * Detatch all the functions offered by the plugins
122
     */
123 1
    public function detach(Plugin ...$plugins): void
124
    {
125 1
        foreach ($plugins as $plugin) {
126 1
            $this->detachPlugin($plugin);
127
        }
128
    }
129
130
    /**
131
     * Detatch all the functions offered by the plugin
132
     *
133
     * @param Plugin $plugin
134
     */
135 1
    public function detachPlugin(Plugin $plugin): void
136
    {
137 1
        foreach ($plugin->getCallablesTable() as $name => $_) {
138 1
            $this->remove($name);
139
        }
140
    }
141
142 3
    public function count(): int
143
    {
144 3
        return count($this->map);
145
    }
146
}
147