PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.1
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.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 / Invoker / Invoker.php

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

110 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1);
2
3 namespace WPDeveloper\BetterDocs\Dependencies\Invoker;
4
5 use WPDeveloper\BetterDocs\Dependencies\Invoker\Exception\NotCallableException;
6 use WPDeveloper\BetterDocs\Dependencies\Invoker\Exception\NotEnoughParametersException;
7 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\AssociativeArrayResolver;
8 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\DefaultValueResolver;
9 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\NumericArrayResolver;
10 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\ParameterResolver;
11 use WPDeveloper\BetterDocs\Dependencies\Invoker\ParameterResolver\ResolverChain;
12 use WPDeveloper\BetterDocs\Dependencies\Invoker\Reflection\CallableReflection;
13 use WPDeveloper\BetterDocs\Dependencies\Psr\Container\ContainerInterface;
14 use ReflectionParameter;
15
16 /**
17 * Invoke a callable.
18 */
19 class Invoker implements InvokerInterface
20 {
21 /** @var CallableResolver|null */
22 private $callableResolver;
23
24 /** @var ParameterResolver */
25 private $parameterResolver;
26
27 /** @var ContainerInterface|null */
28 private $container;
29
30 public function __construct(?ParameterResolver $parameterResolver = null, ?ContainerInterface $container = null)
31 {
32 $this->parameterResolver = $parameterResolver ?: $this->createParameterResolver();
33 $this->container = $container;
34
35 if ($container) {
36 $this->callableResolver = new CallableResolver($container);
37 }
38 }
39
40 /**
41 * {@inheritdoc}
42 */
43 public function call($callable, array $parameters = [])
44 {
45 if ($this->callableResolver) {
46 $callable = $this->callableResolver->resolve($callable);
47 }
48
49 if (! is_callable($callable)) {
50 throw new NotCallableException(sprintf(
51 '%s is not a callable',
52 is_object($callable) ? 'Instance of ' . get_class($callable) : var_export($callable, true)
53 ));
54 }
55
56 $callableReflection = CallableReflection::create($callable);
57
58 $args = $this->parameterResolver->getParameters($callableReflection, $parameters, []);
59
60 // Sort by array key because call_user_func_array ignores numeric keys
61 ksort($args);
62
63 // Check all parameters are resolved
64 $diff = array_diff_key($callableReflection->getParameters(), $args);
65 $parameter = reset($diff);
66 if ($parameter && \assert($parameter instanceof ReflectionParameter) && ! $parameter->isVariadic()) {
67 throw new NotEnoughParametersException(sprintf(
68 'Unable to invoke the callable because no value was given for parameter %d ($%s)',
69 $parameter->getPosition() + 1,
70 $parameter->name
71 ));
72 }
73
74 return call_user_func_array($callable, $args);
75 }
76
77 /**
78 * Create the default parameter resolver.
79 */
80 private function createParameterResolver(): ParameterResolver
81 {
82 return new ResolverChain([
83 new NumericArrayResolver,
84 new AssociativeArrayResolver,
85 new DefaultValueResolver,
86 ]);
87 }
88
89 /**
90 * @return ParameterResolver By default it's a ResolverChain
91 */
92 public function getParameterResolver(): ParameterResolver
93 {
94 return $this->parameterResolver;
95 }
96
97 public function getContainer(): ?ContainerInterface
98 {
99 return $this->container;
100 }
101
102 /**
103 * @return CallableResolver|null Returns null if no container was given in the constructor.
104 */
105 public function getCallableResolver(): ?CallableResolver
106 {
107 return $this->callableResolver;
108 }
109 }
110