PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.4.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.4.0
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Dependencies / DI / CompiledContainer.php

CompiledContainer.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.4.0, at includes/Dependencies/DI/CompiledContainer.php

122 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace WPDeveloper\BetterDocs\Dependencies\DI;
6
7 use WPDeveloper\BetterDocs\Dependencies\DI\Compiler\RequestedEntryHolder;
8 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\Definition;
9 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\Exception\InvalidDefinition;
10 use WPDeveloper\BetterDocs\Dependencies\DI\Invoker\FactoryParameterResolver;
11 use WPDeveloper\BetterDocs\Dependencies\Invoker\Exception\NotCallableException;
12 use WPDeveloper\BetterDocs\Dependencies\Invoker\Exception\NotEnoughParametersException;
13 use WPDeveloper\BetterDocs\Dependencies\Invoker\Invoker;
14 use WPDeveloper\BetterDocs\Dependencies\Invoker\InvokerInterface;
15 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\AssociativeArrayResolver;
16 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\NumericArrayResolver;
17 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\ResolverChain;
18
19 /**
20 * Compiled version of the dependency injection container.
21 *
22 * @author Matthieu Napoli <matthieu@mnapoli.fr>
23 */
24 abstract class CompiledContainer extends Container
25 {
26 /**
27 * @var InvokerInterface
28 */
29 private $factoryInvoker;
30
31 /**
32 * {@inheritdoc}
33 */
34 public function get($name)
35 {
36 // Try to find the entry in the singleton map
37 if (isset($this->resolvedEntries[$name]) || array_key_exists($name, $this->resolvedEntries)) {
38 return $this->resolvedEntries[$name];
39 }
40
41 $method = static::METHOD_MAPPING[$name] ?? null;
42
43 // If it's a compiled entry, then there is a method in this class
44 if ($method !== null) {
45 // Check if we are already getting this entry -> circular dependency
46 if (isset($this->entriesBeingResolved[$name])) {
47 throw new DependencyException("Circular dependency detected while trying to resolve entry '$name'");
48 }
49 $this->entriesBeingResolved[$name] = true;
50
51 try {
52 $value = $this->$method();
53 } finally {
54 unset($this->entriesBeingResolved[$name]);
55 }
56
57 // Store the entry to always return it without recomputing it
58 $this->resolvedEntries[$name] = $value;
59
60 return $value;
61 }
62
63 return parent::get($name);
64 }
65
66 /**
67 * {@inheritdoc}
68 */
69 public function has($name)
70 {
71 if (! is_string($name)) {
72 throw new \InvalidArgumentException(sprintf(
73 'The name parameter must be of type string, %s given',
74 is_object($name) ? get_class($name) : gettype($name)
75 ));
76 }
77
78 // The parent method is overridden to check in our array, it avoids resolving definitions
79 if (isset(static::METHOD_MAPPING[$name])) {
80 return true;
81 }
82
83 return parent::has($name);
84 }
85
86 protected function setDefinition(string $name, Definition $definition)
87 {
88 // It needs to be forbidden because that would mean get() must go through the definitions
89 // every time, which kinds of defeats the performance gains of the compiled container
90 throw new \LogicException('You cannot set a definition at runtime on a compiled container. You can either put your definitions in a file, disable compilation or ->set() a raw value directly (PHP object, string, int, ...) instead of a PHP-WPDeveloper\BetterDocs\Dependencies\DI definition.');
91 }
92
93 /**
94 * Invoke the given callable.
95 */
96 protected function resolveFactory($callable, $entryName, array $extraParameters = [])
97 {
98 // Initialize the factory resolver
99 if (! $this->factoryInvoker) {
100 $parameterResolver = new ResolverChain([
101 new AssociativeArrayResolver,
102 new FactoryParameterResolver($this->delegateContainer),
103 new NumericArrayResolver,
104 ]);
105
106 $this->factoryInvoker = new Invoker($parameterResolver, $this->delegateContainer);
107 }
108
109 $parameters = [$this->delegateContainer, new RequestedEntryHolder($entryName)];
110
111 $parameters = array_merge($parameters, $extraParameters);
112
113 try {
114 return $this->factoryInvoker->call($callable, $parameters);
115 } catch (NotCallableException $e) {
116 throw new InvalidDefinition("Entry \"$entryName\" cannot be resolved: factory " . $e->getMessage());
117 } catch (NotEnoughParametersException $e) {
118 throw new InvalidDefinition("Entry \"$entryName\" cannot be resolved: " . $e->getMessage());
119 }
120 }
121 }
122