Completed
Pull Request — master (#1)
by Pol
01:47 queued 27s
created

DynamicObjectsTrait::hasDynamicProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
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 6
    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 6
    }
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 1
    public static function setDynamicObjectCacheProvider(CacheInterface $cache)
169
    {
170 1
        self::$cache = $cache;
171 1
    }
172
173
    /**
174
     * Get the cache.
175
     *
176
     * @return \Psr\SimpleCache\CacheInterface
177
     */
178 2
    public static function getDynamicObjectCacheProvider()
179
    {
180 2
        if (!isset(self::$cache)) {
181 1
            self::setDynamicObjectCacheProvider(new ArrayCache());
182 1
        }
183
184 2
        return self::$cache;
185
    }
186
187
    /**
188
     * Clear the cache.
189
     */
190
    public static function clearDynamicObjectCache()
191
    {
192
        self::getDynamicObjectCacheProvider()->clear();
193
    }
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']) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209 1
                if ($result = self::getDynamicObjectCacheProvider()->get($cacheid)) {
210 1
                    return $result;
211
                }
212 1
            }
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 1
            }
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 1
        }
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']) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
248 1
                    if ($result = self::getDynamicObjectCacheProvider()->get($cacheid)) {
249 1
                        return $result;
250
                    }
251 1
                }
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 1
                }
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