Completed
Push — master ( 1d70f6...d550e4 )
by Pol
01:34
created

DynamicObjectsTrait::__callStatic()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 4
cts 6
cp 0.6667
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 2
crap 3.3332
1
<?php
2
3
namespace drupol\DynamicObjects;
4
5
use drupol\Memoize\MemoizeTrait;
6
7
/**
8
 * Trait DynamicObjectsTrait.
9
 *
10
 * @package drupol\DynamicObjects
11
 */
12
trait DynamicObjectsTrait
13
{
14
    use MemoizeTrait;
15
16
    /**
17
     * @var array
18
     */
19
    protected static $dynamicMethods = array();
20
21
    /**
22
     * @var array
23
     */
24
    protected static $dynamicProperties = array();
25
26
    /**
27
     * Add a dynamic property.
28
     *
29
     * @param string $name
30
     *   The property name.
31
     * @param mixed $value
32
     *   The property value.
33
     * @param bool $memoize
34
     *   Memoize parameter.
35
     */
36 5
    public static function addDynamicProperty($name, $value, $memoize = false)
37
    {
38 5
        static::$dynamicProperties[get_called_class()][$name] = [
39 5
            'name' => $name,
40 5
            'factory' => $value,
41 5
            'memoize' => $memoize,
42
        ];
43 5
    }
44
45
    /**
46
     * Add a dynamic method.
47
     *
48
     * @param $name
49
     *   The method name.
50
     * @param \Closure $func
51
     *   The method.
52
     * @param bool $memoize
53
     *   Memoize parameter.
54
     * @param bool $static
55
     *   Static flag parameter.
56
     */
57 4
    public static function addDynamicMethod($name, \Closure $func, $memoize = false, $static = false)
58
    {
59 4
        static::$dynamicMethods[get_called_class()][$name] = [
60 4
            'name' => $name,
61 4
            'factory' => $func,
62 4
            'memoize' => $memoize,
63 4
            'static' => $static,
64
        ];
65 4
    }
66
67
    /**
68
     * Check if a dynamic property exists.
69
     *
70
     * @param string $name
71
     *   The property name.
72
     * @return bool
73
     *   True if the property exists, false otherwise.
74
     */
75 8
    public static function hasDynamicProperty($name)
76
    {
77 8
        return isset(static::$dynamicProperties[get_called_class()][$name]);
78
    }
79
80
    /**
81
     * Check if a dynamic method exists.
82
     *
83
     * @param string $name
84
     *   The property name.
85
     * @return bool
86
     *   True if the property exists, false otherwise.
87
     */
88 6
    public static function hasDynamicMethod($name)
89
    {
90 6
        return isset(static::$dynamicMethods[get_called_class()][$name]);
91
    }
92
93
    /**
94
     * Get a dynamic property.
95
     *
96
     * @param $name
97
     *   The property name.
98
     * @return mixed|null
99
     *   The property value if it exists, null otherwise.
100
     */
101 4
    public static function getDynamicProperty($name)
102
    {
103 4
        if (static::hasDynamicProperty($name)) {
104 3
            return static::$dynamicProperties[get_called_class()][$name];
105
        }
106
107 1
        return null;
108
    }
109
110
    /**
111
     * Get a dynamic method.
112
     *
113
     * @param $name
114
     *   The method name.
115
     * @return mixed|null
116
     *   The method if it exists, null otherwise.
117
     */
118 3
    public static function getDynamicMethod($name)
119
    {
120 3
        return ( static::hasDynamicMethod($name) ) ?
121 3
            static::$dynamicMethods[get_called_class()][$name] : null;
122
    }
123
124
    /**
125
     * Clear dynamic properties.
126
     */
127 1
    public static function clearDynamicProperties()
128
    {
129 1
        static::$dynamicProperties[get_called_class()] = array();
130 1
    }
131
132
    /**
133
     * Clear dynamic methods.
134
     */
135 1
    public static function clearDynamicMethods()
136
    {
137 1
        static::$dynamicMethods[get_called_class()] = array();
138 1
    }
139
140
    /**
141
     * Remove a dynamic property.
142
     *
143
     * @param string $name
144
     *   The property name.
145
     */
146 1
    public static function removeDynamicProperty($name)
147
    {
148 1
        unset(static::$dynamicProperties[get_called_class()][$name]);
149 1
    }
150
151
    /**
152
     * Remove a dynamic method.
153
     *
154
     * @param string $name
155
     *   The method name.
156
     */
157 1
    public static function removeDynamicMethod($name)
158
    {
159 1
        unset(static::$dynamicMethods[get_called_class()][$name]);
160 1
    }
161
162
    /**
163
     * Execute a closure.
164
     *
165
     * @param \Closure $func
166
     *   The closure.
167
     * @param array $parameters
168
     *   The closure's parameters.
169
     * @param bool $memoize
170
     *   The memoize parameter.
171
     *
172
     * @return mixed|null
173
     *   The return of the closure.
174
     *
175
     * @throws \Psr\SimpleCache\InvalidArgumentException
176
     */
177 4
    public function doDynamicRequest(\Closure $func, array $parameters = [], $memoize = false)
178
    {
179 4
        if (!class_exists('\drupol\Memoize\Memoize') || false === $memoize) {
180 4
            $memoize = false;
181
        }
182
183 4
        if (true === $memoize) {
184 2
            return $this->memoize($func, $parameters);
185
        }
186
187 4
        return call_user_func_array($func, $parameters);
188
    }
189
190
    /**
191
     * @param $method
192
     * @param array $parameters
193
     *
194
     * @return mixed
195
     * @throws \Psr\SimpleCache\InvalidArgumentException
196
     */
197 3
    public function __call($method, array $parameters = array())
198
    {
199 3
        if ($data = static::getDynamicMethod($method)) {
200 2
            return $this->doDynamicRequest($data['factory'], $parameters, $data['memoize']);
201
        }
202
203 1
        throw new \BadMethodCallException(sprintf('Undefined method: %s().', $method));
204
    }
205
206
    /**
207
     * @param $method
208
     * @param array $parameters
209
     *
210
     * @return mixed
211
     * @throws \Psr\SimpleCache\InvalidArgumentException
212
     */
213 1
    public static function __callStatic($method, array $parameters = array())
214
    {
215 1
        $instance = new static();
216
217 1
        if ($data = static::getDynamicMethod($method)) {
218
            if (true == $data['static']) {
219
                return $instance->doDynamicRequest($data['factory'], $parameters, $data['memoize']);
220
            }
221
        }
222
223 1
        throw new \BadMethodCallException(sprintf('Undefined static method: %s().', $method));
224
    }
225
226
    /**
227
     * {inheritdoc}
228
     */
229 4
    public function __get($property)
230
    {
231 4
        if ($data = static::getDynamicProperty($property)) {
232 3
            $return = $data['factory'];
233
234 3
            if (is_callable($data['factory'])) {
235 2
                $return = $this->doDynamicRequest($data['factory'], [], $data['memoize']);
236
            }
237
238 3
            return $return;
239
        }
240
241 1
        throw new \DomainException(sprintf('Undefined property: %s.', $property));
242
    }
243
244
    /**
245
     * {inheritdoc}
246
     */
247 3
    public function __set($property, $value)
248
    {
249 3
        if (static::hasDynamicProperty($property)) {
250 1
            static::addDynamicProperty($property, $value);
251
        }
252 3
    }
253
}
254