PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.3.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.3.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / vendor / mrclay / props-dic / src / Props / Container.php

Container.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.3.0, at vendor/mrclay/props-dic/src/Props/Container.php

250 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Props;
4
5 use Psr\Container\ContainerInterface;
6
7 /**
8 * Container holding values which can be resolved upon reading and optionally stored and shared
9 * across reads.
10 *
11 * Values are read/set as properties.
12 *
13 * @note see scripts/example.php
14 */
15 class Container implements ContainerInterface
16 {
17 /**
18 * @var callable[]
19 */
20 private $factories = array();
21
22 /**
23 * @var array
24 */
25 private $cache = array();
26
27 /**
28 * Fetch a value.
29 *
30 * @param string $name
31 * @return mixed
32 * @throws FactoryUncallableException|ValueUnresolvableException|NotFoundException
33 */
34 public function __get($name)
35 {
36 if (array_key_exists($name, $this->cache)) {
37 return $this->cache[$name];
38 }
39 $value = $this->build($name);
40 $this->cache[$name] = $value;
41 return $value;
42 }
43
44 /**
45 * {@inheritdoc}
46 */
47 public function get($name)
48 {
49 return $this->__get($name);
50 }
51
52 /**
53 * Set a value.
54 *
55 * @param string $name
56 * @param mixed $value
57 * @throws \InvalidArgumentException
58 */
59 public function __set($name, $value)
60 {
61 if ($value instanceof \Closure) {
62 $this->setFactory($name, $value);
63 return;
64 }
65
66 $this->cache[$name] = $value;
67 unset($this->factories[$name]);
68 }
69
70 /**
71 * Set a value to be later returned as is. You only need to use this if you wish to store
72 * a Closure.
73 *
74 * @param string $name
75 * @param mixed $value
76 * @throws \InvalidArgumentException
77 */
78 public function setValue($name, $value)
79 {
80 unset($this->factories[$name]);
81 $this->cache[$name] = $value;
82 }
83
84 /**
85 * @param string $name
86 */
87 public function __unset($name)
88 {
89 unset($this->cache[$name]);
90 unset($this->factories[$name]);
91 }
92
93 /**
94 * @param string $name
95 * @return bool
96 */
97 public function __isset($name)
98 {
99 return array_key_exists($name, $this->factories) || array_key_exists($name, $this->cache);
100 }
101
102 /**
103 * {@inheritdoc}
104 */
105 public function has($name)
106 {
107 return $this->__isset($name);
108 }
109
110 /**
111 * Fetch a freshly-resolved value.
112 *
113 * @param string $method method name must start with "new_"
114 * @param array $args
115 * @return mixed
116 * @throws BadMethodCallException
117 */
118 public function __call($method, $args)
119 {
120 if (0 !== strpos($method, 'new_')) {
121 throw new BadMethodCallException("Method name must begin with 'new_'");
122 }
123
124 return $this->build(substr($method, 4));
125 }
126
127 /**
128 * Can we fetch a new value via new_$name()?
129 *
130 * @param string $name
131 * @return bool
132 */
133 public function hasFactory($name)
134 {
135 return array_key_exists($name, $this->factories);
136 }
137
138 /**
139 * Set a factory to generate a value when the container is read.
140 *
141 * @param string $name The name of the value
142 * @param callable $factory Factory for the value
143 * @throws FactoryUncallableException
144 */
145 public function setFactory($name, $factory)
146 {
147 if (!is_callable($factory, true)) {
148 throw new FactoryUncallableException('$factory must appear callable');
149 }
150
151 unset($this->cache[$name]);
152 $this->factories[$name] = $factory;
153 }
154
155 /**
156 * Get an already-set factory callable (Closure, invokable, or callback)
157 *
158 * @param string $name The name of the value
159 * @return callable
160 * @throws NotFoundException
161 */
162 public function getFactory($name)
163 {
164 if (!array_key_exists($name, $this->factories)) {
165 throw new NotFoundException("No factory available for: $name");
166 }
167
168 return $this->factories[$name];
169 }
170
171 /**
172 * Add a function that gets applied to the return value of an existing factory
173 *
174 * @note A cached value (from a previous property read) will thrown away. The next property read
175 * (and all new_NAME() calls) will call the original factory.
176 *
177 * @param string $name The name of the value
178 * @param callable $extender Function that is applied to extend the returned value
179 * @return \Closure
180 * @throws FactoryUncallableException|NotFoundException
181 */
182 public function extend($name, $extender)
183 {
184 if (!is_callable($extender, true)) {
185 throw new FactoryUncallableException('$extender must appear callable');
186 }
187
188 if (!array_key_exists($name, $this->factories)) {
189 throw new NotFoundException("No factory available for: $name");
190 }
191
192 $factory = $this->factories[$name];
193
194 $newFactory = function (Container $c) use ($extender, $factory) {
195 return call_user_func($extender, call_user_func($factory, $c), $c);
196 };
197
198 $this->setFactory($name, $newFactory);
199
200 return $newFactory;
201 }
202
203 /**
204 * Get all keys available
205 *
206 * @return string[]
207 */
208 public function getKeys()
209 {
210 $keys = array_keys($this->cache) + array_keys($this->factories);
211 return array_unique($keys);
212 }
213
214 /**
215 * Build a value
216 *
217 * @param string $name
218 * @return mixed
219 * @throws FactoryUncallableException|ValueUnresolvableException|NotFoundException
220 */
221 private function build($name)
222 {
223 if (!array_key_exists($name, $this->factories)) {
224 throw new NotFoundException("Missing value: $name");
225 }
226
227 $factory = $this->factories[$name];
228
229 if (is_callable($factory)) {
230 try {
231 return call_user_func($factory, $this);
232 } catch (\Exception $e) {
233 throw new ValueUnresolvableException("Factory for '$name' threw an exception.", 0, $e);
234 }
235 }
236
237 $msg = "Factory for '$name' was uncallable";
238 if (is_string($factory)) {
239 $msg .= ": '$factory'";
240 } elseif (is_array($factory)) {
241 if (is_string($factory[0])) {
242 $msg .= ": '{$factory[0]}::{$factory[1]}'";
243 } else {
244 $msg .= ": " . get_class($factory[0]) . "->{$factory[1]}";
245 }
246 }
247 throw new FactoryUncallableException($msg);
248 }
249 }
250