PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.6.1
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.6.1
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.6.1, at includes/Dependencies/DI/CompiledContainer.php

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