Server : Apache System : Linux ls31.server.ly 3.10.0-962.3.2.lve1.5.68.el7.x86_64 #1 SMP Wed Apr 6 11:12:23 UTC 2022 x86_64 User : medchoco ( 2906) PHP Version : 8.3.16 Disable Function : mail Directory : /home/medchoco/www/wp-content/plugins/wp-optimize/vendor/mrclay/props-dic/src/Props/ |
Upload File : |
<?php namespace Props; use Psr\Container\ContainerInterface; /** * Container holding values which can be resolved upon reading and optionally stored and shared * across reads. * * Values are read/set as properties. * * @note see scripts/example.php */ class Container implements ContainerInterface { /** * @var callable[] */ private $factories = array(); /** * @var array */ private $cache = array(); /** * Fetch a value. * * @param string $name * @return mixed * @throws FactoryUncallableException|ValueUnresolvableException|NotFoundException */ public function __get($name) { if (array_key_exists($name, $this->cache)) { return $this->cache[$name]; } $value = $this->build($name); $this->cache[$name] = $value; return $value; } /** * {@inheritdoc} */ public function get($name) { return $this->__get($name); } /** * Set a value. * * @param string $name * @param mixed $value * @throws \InvalidArgumentException */ public function __set($name, $value) { if ($value instanceof \Closure) { $this->setFactory($name, $value); return; } $this->cache[$name] = $value; unset($this->factories[$name]); } /** * Set a value to be later returned as is. You only need to use this if you wish to store * a Closure. * * @param string $name * @param mixed $value * @throws \InvalidArgumentException */ public function setValue($name, $value) { unset($this->factories[$name]); $this->cache[$name] = $value; } /** * @param string $name */ public function __unset($name) { unset($this->cache[$name]); unset($this->factories[$name]); } /** * @param string $name * @return bool */ public function __isset($name) { return array_key_exists($name, $this->factories) || array_key_exists($name, $this->cache); } /** * {@inheritdoc} */ public function has($name) { return $this->__isset($name); } /** * Fetch a freshly-resolved value. * * @param string $method method name must start with "new_" * @param array $args * @return mixed * @throws BadMethodCallException */ public function __call($method, $args) { if (0 !== strpos($method, 'new_')) { throw new BadMethodCallException("Method name must begin with 'new_'"); } return $this->build(substr($method, 4)); } /** * Can we fetch a new value via new_$name()? * * @param string $name * @return bool */ public function hasFactory($name) { return array_key_exists($name, $this->factories); } /** * Set a factory to generate a value when the container is read. * * @param string $name The name of the value * @param callable $factory Factory for the value * @throws FactoryUncallableException */ public function setFactory($name, $factory) { if (!is_callable($factory, true)) { throw new FactoryUncallableException('$factory must appear callable'); } unset($this->cache[$name]); $this->factories[$name] = $factory; } /** * Get an already-set factory callable (Closure, invokable, or callback) * * @param string $name The name of the value * @return callable * @throws NotFoundException */ public function getFactory($name) { if (!array_key_exists($name, $this->factories)) { throw new NotFoundException("No factory available for: $name"); } return $this->factories[$name]; } /** * Add a function that gets applied to the return value of an existing factory * * @note A cached value (from a previous property read) will thrown away. The next property read * (and all new_NAME() calls) will call the original factory. * * @param string $name The name of the value * @param callable $extender Function that is applied to extend the returned value * @return \Closure * @throws FactoryUncallableException|NotFoundException */ public function extend($name, $extender) { if (!is_callable($extender, true)) { throw new FactoryUncallableException('$extender must appear callable'); } if (!array_key_exists($name, $this->factories)) { throw new NotFoundException("No factory available for: $name"); } $factory = $this->factories[$name]; $newFactory = function (Container $c) use ($extender, $factory) { return call_user_func($extender, call_user_func($factory, $c), $c); }; $this->setFactory($name, $newFactory); return $newFactory; } /** * Get all keys available * * @return string[] */ public function getKeys() { $keys = array_keys($this->cache) + array_keys($this->factories); return array_unique($keys); } /** * Build a value * * @param string $name * @return mixed * @throws FactoryUncallableException|ValueUnresolvableException|NotFoundException */ private function build($name) { if (!array_key_exists($name, $this->factories)) { throw new NotFoundException("Missing value: $name"); } $factory = $this->factories[$name]; if (is_callable($factory)) { try { return call_user_func($factory, $this); } catch (\Exception $e) { throw new ValueUnresolvableException("Factory for '$name' threw an exception.", 0, $e); } } $msg = "Factory for '$name' was uncallable"; if (is_string($factory)) { $msg .= ": '$factory'"; } elseif (is_array($factory)) { if (is_string($factory[0])) { $msg .= ": '{$factory[0]}::{$factory[1]}'"; } else { $msg .= ": " . get_class($factory[0]) . "->{$factory[1]}"; } } throw new FactoryUncallableException($msg); } }