Completed
Push — master ( feccbc...1ad1cd )
by Pol
01:28
created

setDynamicObjectCacheProvider()   A

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