Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
parameter.php
1<?php
2
4
7
9{
10 private string $className;
11 private \Closure $constructor;
13 private $externalNameConstructor;
14
15 public function __construct(string $className, \Closure $constructor, \Closure $externalNameConstructor = null)
16 {
17 $this
18 ->setClassName($className)
19 ->setConstructor($constructor)
20 ;
21
22 $reflectionFunction = new \ReflectionFunction($constructor);
23 if ($reflectionFunction->getNumberOfParameters() > 1)
24 {
25 if ($externalNameConstructor === null)
26 {
27 $externalNameConstructor = static function(\ReflectionParameter $parameter){
28 return $parameter->getName() . 'Id';
29 };
30 }
31
32 $this->setExternalNameConstructor($externalNameConstructor);
33 }
34
35 }
36
37 public function getPriority()
38 {
39 if (!$this->needToMapExternalData())
40 {
41 return 1;
42 }
43
44 return 2;
45 }
46
47 public function constructValue(\ReflectionParameter $parameter, Result $captureResult, $newThis = null)
48 {
49 $reflectionClass = $this->buildReflectionClass($parameter);
50 if (!$reflectionClass)
51 {
52 throw new BinderArgumentException("Could not retrieve \\ReflectionClass for {$parameter->getName()}.");
53 }
54
55 $paramsToInvoke = array_merge(
56 [$reflectionClass->getName()],
57 $captureResult->getData()
58 );
59
60 return $this->callConstructor(
61 $this->getConstructor(),
62 $paramsToInvoke,
63 $newThis,
64 );
65 }
66
67 protected function callConstructor(\Closure $constructor, array $params, $newThis = null)
68 {
69 if ($newThis && $this->isBindable($constructor))
70 {
71 $constructor->bindTo($newThis);
72 }
73
74 return call_user_func_array($constructor, $params);
75 }
76
77 private function isBindable(\Closure $closure): bool
78 {
79 $reflectionClosure = new \ReflectionFunction($closure);
80 $isBindable = ($reflectionClosure->getClosureThis() !== null || $reflectionClosure->getClosureScopeClass() === null);
81
82 return $isBindable;
83 }
84
85 public function captureData(\ReflectionParameter $parameter, array $sourceParameters, array $autoWiredParameters = [])
86 {
87 if (!$this->needToMapExternalData())
88 {
89 return new Result();
90 }
91
92 $result = new Result();
93 $externalName = $this->generateExternalName($parameter);
94 $value = $this->findParameterInSourceList($externalName, $sourceParameters, $status);
95
96 if ($status === Binder::STATUS_NOT_FOUND)
97 {
98 $result->addError(new Error("Could not find value for {{$externalName}}"));
99 }
100 else
101 {
102 $result->setData([
103 $value
104 ]);
105 }
106
107 return $result;
108 }
109
110 protected function findParameterInSourceList($name, array $sourceParameters, &$status)
111 {
112 $status = Binder::STATUS_FOUND;
113 foreach ($sourceParameters as $source)
114 {
115 if (isset($source[$name]))
116 {
117 return $source[$name];
118 }
119
120 if (($source instanceof \ArrayAccess) && $source->offsetExists($name))
121 {
122 return $source[$name];
123 }
124
125 if (is_array($source) && array_key_exists($name, $source))
126 {
127 return $source[$name];
128 }
129 }
130 $status = Binder::STATUS_NOT_FOUND;
131
132 return null;
133 }
134
135 protected function buildReflectionClass(\ReflectionParameter $parameter): ?\ReflectionClass
136 {
137 $namedType = $parameter->getType();
138 if (!($namedType instanceof \ReflectionNamedType))
139 {
140 return null;
141 }
142 if ($namedType->isBuiltin())
143 {
144 return null;
145 }
146
147 return new \ReflectionClass($namedType->getName());
148 }
149
150 public function match(\ReflectionParameter $parameter)
151 {
152 $class = $this->buildReflectionClass($parameter);
153 if (!$class)
154 {
155 return false;
156 }
157
158 return
159 $class->isSubclassOf($this->getClassName()) ||
160 $class->name === ltrim($this->getClassName(), '\\')
161 ;
162 }
163
167 public function getClassName()
168 {
169 return $this->className;
170 }
171
177 public function setClassName($className)
178 {
179 $this->className = $className;
180
181 return $this;
182 }
183
187 public function getConstructor()
188 {
189 return $this->constructor;
190 }
191
197 public function setConstructor(\Closure $constructor)
198 {
199 $this->constructor = $constructor;
200
201 return $this;
202 }
203
208 {
209 return $this->externalNameConstructor;
210 }
211
217 public function setExternalNameConstructor(\Closure $externalNameConstructor)
218 {
219 $this->externalNameConstructor = $externalNameConstructor;
220
221 return $this;
222 }
223
224 protected function needToMapExternalData()
225 {
226 return $this->externalNameConstructor !== null;
227 }
228
229 public function generateExternalName()
230 {
231 return call_user_func_array($this->getExternalNameConstructor(), func_get_args());
232 }
233}
match(\ReflectionParameter $parameter)
callConstructor(\Closure $constructor, array $params, $newThis=null)
Definition parameter.php:67
constructValue(\ReflectionParameter $parameter, Result $captureResult, $newThis=null)
Definition parameter.php:47
captureData(\ReflectionParameter $parameter, array $sourceParameters, array $autoWiredParameters=[])
Definition parameter.php:85
buildReflectionClass(\ReflectionParameter $parameter)
findParameterInSourceList($name, array $sourceParameters, &$status)
setExternalNameConstructor(\Closure $externalNameConstructor)
__construct(string $className, \Closure $constructor, \Closure $externalNameConstructor=null)
Definition parameter.php:15
setConstructor(\Closure $constructor)