This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
5 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
6 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||
7 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
8 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
9 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||
10 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||
11 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||
12 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
13 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
14 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
15 | * |
||
16 | * This software consists of voluntary contributions made by many individuals |
||
17 | * and is licensed under the LGPL. For more information please see |
||
18 | * <http://phing.info>. |
||
19 | */ |
||
20 | |||
21 | namespace Phing; |
||
22 | |||
23 | use Phing\Exception\BuildException; |
||
24 | use Phing\Type\PropertyValue; |
||
25 | use Phing\Util\StringHelper; |
||
26 | |||
27 | /** |
||
28 | * Component creation and configuration. |
||
29 | * |
||
30 | * @author Siad Ardroumli <[email protected]> |
||
31 | */ |
||
32 | class PropertyHelper |
||
33 | { |
||
34 | /** |
||
35 | * @var Project |
||
36 | */ |
||
37 | private $project; |
||
38 | |||
39 | /** |
||
40 | * @var null|PropertyHelper |
||
41 | */ |
||
42 | private $next; |
||
43 | |||
44 | /** |
||
45 | * Project properties map (usually String to String). |
||
46 | */ |
||
47 | private $properties = []; |
||
48 | |||
49 | /** |
||
50 | * Map of "user" properties (as created in the Ant task, for example). |
||
51 | * Note that these key/value pairs are also always put into the |
||
52 | * project properties, so only the project properties need to be queried. |
||
53 | * Mapping is String to String. |
||
54 | */ |
||
55 | private $userProperties = []; |
||
56 | |||
57 | /** |
||
58 | * Map of inherited "user" properties - that are those "user" |
||
59 | * properties that have been created by tasks and not been set |
||
60 | * from the command line or a GUI tool. |
||
61 | * Mapping is String to String. |
||
62 | */ |
||
63 | private $inheritedProperties = []; |
||
64 | |||
65 | /** |
||
66 | * There are 2 ways to hook into property handling: |
||
67 | * - you can replace the main PropertyHelper. The replacement is required |
||
68 | * to support the same semantics (of course :-). |
||
69 | * |
||
70 | * - you can chain a property helper capable of storing some properties. |
||
71 | * Again, you are required to respect the immutability semantics (at |
||
72 | * least for non-dynamic properties) |
||
73 | * |
||
74 | * @param PropertyHelper $next the next property helper in the chain |
||
75 | */ |
||
76 | public function setNext(PropertyHelper $next): void |
||
77 | { |
||
78 | $this->next = $next; |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * Get the next property helper in the chain. |
||
83 | * |
||
84 | * @return null|PropertyHelper the next property helper |
||
85 | */ |
||
86 | 926 | public function getNext(): ?PropertyHelper |
|
87 | { |
||
88 | 926 | return $this->next; |
|
89 | } |
||
90 | |||
91 | /** |
||
92 | * Factory method to create a property processor. |
||
93 | * Users can provide their own or replace it using "ant.PropertyHelper" |
||
94 | * reference. User tasks can also add themselves to the chain, and provide |
||
95 | * dynamic properties. |
||
96 | * |
||
97 | * @param Project $project the project fro which the property helper is required |
||
98 | * |
||
99 | * @return PropertyHelper the project's property helper |
||
100 | */ |
||
101 | 928 | public static function getPropertyHelper(Project $project): PropertyHelper |
|
102 | { |
||
103 | /** |
||
104 | * @var PropertyHelper $helper |
||
105 | */ |
||
106 | 928 | $helper = $project->getReference('phing.PropertyHelper'); |
|
107 | 928 | if (null !== $helper) { |
|
108 | 907 | return $helper; |
|
109 | } |
||
110 | 928 | $helper = new self(); |
|
111 | 928 | $helper->setProject($project); |
|
112 | |||
113 | 928 | $project->addReference('phing.PropertyHelper', $helper); |
|
114 | |||
115 | 928 | return $helper; |
|
116 | } |
||
117 | |||
118 | // -------------------- Methods to override -------------------- |
||
119 | |||
120 | /** |
||
121 | * Sets a property. Any existing property of the same name |
||
122 | * is overwritten, unless it is a user property. Will be called |
||
123 | * from setProperty(). |
||
124 | * |
||
125 | * If all helpers return false, the property will be saved in |
||
126 | * the default properties table by setProperty. |
||
127 | * |
||
128 | * @param string $ns the namespace that the property is in (currently |
||
129 | * not used |
||
130 | * @param string $name The name of property to set. |
||
131 | * Must not be |
||
132 | * <code>null</code>. |
||
133 | * @param string $value The new value of the property. |
||
134 | * Must not be <code>null</code>. |
||
135 | * @param bool $inherited true if this property is inherited (an [sub]ant[call] property) |
||
136 | * @param bool $user true if this property is a user property |
||
137 | * @param bool $isNew true is this is a new property |
||
138 | * |
||
139 | * @return bool true if this helper has stored the property, false if it |
||
140 | * couldn't. Each helper should delegate to the next one (unless it |
||
141 | * has a good reason not to). |
||
142 | */ |
||
143 | 925 | public function setPropertyHook($ns, $name, $value, $inherited, $user, $isNew): bool |
|
144 | { |
||
145 | 925 | return null !== $this->getNext() |
|
146 | 925 | && $this->getNext()->setPropertyHook($ns, $name, $value, $inherited, $user, $isNew); |
|
147 | } |
||
148 | |||
149 | /** |
||
150 | * Get a property. If all hooks return null, the default |
||
151 | * tables will be used. |
||
152 | * |
||
153 | * @param string $ns namespace of the sought property |
||
154 | * @param string $name name of the sought property |
||
155 | * @param bool $user true if this is a user property |
||
156 | * |
||
157 | * @return null|string the property, if returned by a hook, or null if none |
||
158 | */ |
||
159 | 907 | public function getPropertyHook($ns, $name, $user): ?string |
|
160 | { |
||
161 | 907 | if (null !== $this->getNext()) { |
|
162 | $o = $this->getNext()->getPropertyHook($ns, $name, $user); |
||
163 | if (null !== $o) { |
||
164 | return $o; |
||
165 | } |
||
166 | } |
||
167 | |||
168 | 907 | if (null !== $this->project && StringHelper::startsWith('toString:', $name)) { |
|
169 | 1 | $name = StringHelper::substring($name, strlen('toString:')); |
|
170 | 1 | $v = $this->project->getReference($name); |
|
171 | |||
172 | 1 | return (null === $v) ? null : (string) $v; |
|
173 | } |
||
174 | |||
175 | 907 | return null; |
|
176 | } |
||
177 | |||
178 | // -------------------- Optional methods -------------------- |
||
179 | // You can override those methods if you want to optimize or |
||
180 | // do advanced things (like support a special syntax). |
||
181 | // The methods do not chain - you should use them when embedding ant |
||
182 | // (by replacing the main helper) |
||
183 | |||
184 | /** |
||
185 | * Replaces <code>${xxx}</code> style constructions in the given value |
||
186 | * with the string value of the corresponding data types. |
||
187 | * |
||
188 | * @param string $value The string to be scanned for property references. |
||
189 | * May be <code>null</code>, in which case this |
||
190 | * method returns immediately with no effect. |
||
191 | * @param string[] $keys Mapping (String to String) of property names to their |
||
192 | * values. If <code>null</code>, only project properties |
||
193 | * will be used. |
||
194 | * |
||
195 | * @throws BuildException if the string contains an opening |
||
196 | * <code>${</code> without a closing |
||
197 | * <code>}</code> |
||
198 | * |
||
199 | * @return string the original string with the properties replaced, or |
||
200 | * <code>null</code> if the original string is <code>null</code> |
||
201 | */ |
||
202 | 764 | public function replaceProperties(?string $value, ?array $keys): ?string |
|
203 | { |
||
204 | 764 | if (null === $value) { |
|
205 | return null; |
||
206 | } |
||
207 | 764 | if (null === $keys) { |
|
0 ignored issues
–
show
introduced
by
![]() |
|||
208 | 1 | $keys = $this->project->getProperties(); |
|
209 | } |
||
210 | // Because we're not doing anything special (like multiple passes), |
||
211 | // regex is the simplest / fastest. PropertyTask, though, uses |
||
212 | // the old parsePropertyString() method, since it has more stringent |
||
213 | // requirements. |
||
214 | |||
215 | 764 | $sb = $value; |
|
216 | 764 | $iteration = 0; |
|
217 | // loop to recursively replace tokens |
||
218 | 764 | while (false !== strpos($sb, '${')) { |
|
219 | 463 | $sb = preg_replace_callback( |
|
220 | 463 | '/\$\{([^\$}]+)\}/', |
|
221 | 463 | function ($matches) use ($keys) { |
|
222 | 463 | $propertyName = $matches[1]; |
|
223 | |||
224 | 463 | $replacement = null; |
|
225 | 463 | if (array_key_exists($propertyName, $keys)) { |
|
226 | 456 | $replacement = $keys[$propertyName]; |
|
227 | } |
||
228 | |||
229 | 463 | if (null === $replacement) { |
|
230 | 11 | $replacement = $this->getProperty(null, $propertyName); |
|
231 | } |
||
232 | |||
233 | 463 | if (null === $replacement) { |
|
234 | 10 | $this->project->log( |
|
235 | 10 | 'Property ${' . $propertyName . '} has not been set.', |
|
236 | 10 | Project::MSG_VERBOSE |
|
237 | 10 | ); |
|
238 | |||
239 | 10 | return $matches[0]; |
|
240 | } |
||
241 | |||
242 | 457 | $this->project->log( |
|
243 | 457 | 'Property ${' . $propertyName . '} => ' . (string) $replacement, |
|
244 | 457 | Project::MSG_VERBOSE |
|
245 | 457 | ); |
|
246 | |||
247 | 457 | return $replacement; |
|
248 | 463 | }, |
|
249 | 463 | $sb |
|
250 | 463 | ); |
|
251 | |||
252 | // keep track of iterations so we can break out of otherwise infinite loops. |
||
253 | 463 | ++$iteration; |
|
254 | 463 | if (5 === $iteration) { |
|
255 | 10 | return $sb; |
|
256 | } |
||
257 | } |
||
258 | |||
259 | 763 | return $sb; |
|
260 | } |
||
261 | |||
262 | // -------------------- Default implementation -------------------- |
||
263 | // Methods used to support the default behavior and provide backward |
||
264 | // compatibility. Some will be deprecated, you should avoid calling them. |
||
265 | |||
266 | /** |
||
267 | * Default implementation of setProperty. Will be called from Project. |
||
268 | * This is the original 1.5 implementation, with calls to the hook |
||
269 | * added. |
||
270 | * |
||
271 | * @param string $ns the namespace for the property (currently not used) |
||
272 | * @param string $name the name of the property |
||
273 | * @param string $value the value to set the property to |
||
274 | * @param bool $verbose if this is true output extra log messages |
||
275 | * |
||
276 | * @return bool true if the property is set |
||
277 | */ |
||
278 | 925 | public function setProperty($ns, $name, $value, $verbose): bool |
|
279 | { |
||
280 | // user (CLI) properties take precedence |
||
281 | 925 | if (isset($this->userProperties[$name])) { |
|
282 | 25 | if ($verbose) { |
|
283 | $this->project->log('Override ignored for user property ' . $name, Project::MSG_VERBOSE); |
||
284 | } |
||
285 | |||
286 | 25 | return false; |
|
287 | } |
||
288 | |||
289 | 925 | $done = $this->setPropertyHook($ns, $name, $value, false, false, false); |
|
290 | 925 | if ($done) { |
|
291 | return true; |
||
292 | } |
||
293 | |||
294 | 925 | if ($verbose && isset($this->properties[$name])) { |
|
295 | 4 | $this->project->log( |
|
296 | 4 | 'Overriding previous definition of property ' . $name, |
|
297 | 4 | Project::MSG_VERBOSE |
|
298 | 4 | ); |
|
299 | } |
||
300 | |||
301 | 925 | if ($verbose) { |
|
302 | 260 | $this->project->log( |
|
303 | 260 | 'Setting project property: ' . $name . ' -> ' |
|
304 | 260 | . $value, |
|
305 | 260 | Project::MSG_DEBUG |
|
306 | 260 | ); |
|
307 | } |
||
308 | 925 | $this->properties[$name] = $value; |
|
309 | 925 | $this->project->addReference($name, new PropertyValue($value)); |
|
310 | |||
311 | 925 | return true; |
|
312 | } |
||
313 | |||
314 | /** |
||
315 | * Sets a property if no value currently exists. If the property |
||
316 | * exists already, a message is logged and the method returns with |
||
317 | * no other effect. |
||
318 | * |
||
319 | * @param string $ns the namespace for the property (currently not used) |
||
320 | * @param string $name the name of property to set |
||
321 | * @param string $value the new value of the property |
||
322 | */ |
||
323 | 556 | public function setNewProperty($ns, string $name, string $value): void |
|
324 | { |
||
325 | 556 | if (isset($this->properties[$name])) { |
|
326 | 6 | $this->project->log('Override ignored for property ' . $name, Project::MSG_VERBOSE); |
|
327 | |||
328 | 6 | return; |
|
329 | } |
||
330 | |||
331 | 554 | $done = $this->setPropertyHook($ns, $name, $value, false, false, true); |
|
332 | 554 | if ($done) { |
|
333 | return; |
||
334 | } |
||
335 | |||
336 | 554 | $this->project->log('Setting project property: ' . $name . ' -> ' . $value, Project::MSG_DEBUG); |
|
337 | 554 | if (null !== $name && null !== $value) { |
|
0 ignored issues
–
show
|
|||
338 | 554 | $this->properties[$name] = $value; |
|
339 | 554 | $this->project->addReference($name, new PropertyValue($value)); |
|
340 | } |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * Sets a user property, which cannot be overwritten by |
||
345 | * set/unset property calls. Any previous value is overwritten. |
||
346 | * |
||
347 | * @param string $ns the namespace for the property (currently not used) |
||
348 | * @param string $name the name of property to set |
||
349 | * @param string $value the new value of the property |
||
350 | */ |
||
351 | 906 | public function setUserProperty($ns, string $name, string $value): void |
|
352 | { |
||
353 | 906 | if (null === $name || null === $value) { |
|
0 ignored issues
–
show
|
|||
354 | return; |
||
355 | } |
||
356 | 906 | $this->project->log('Setting ro project property: ' . $name . ' -> ' . $value, Project::MSG_DEBUG); |
|
357 | 906 | $this->userProperties[$name] = $value; |
|
358 | |||
359 | 906 | $done = $this->setPropertyHook($ns, $name, $value, false, true, false); |
|
360 | 906 | if ($done) { |
|
361 | return; |
||
362 | } |
||
363 | 906 | $this->properties[$name] = $value; |
|
364 | 906 | $this->project->addReference($name, new PropertyValue($value)); |
|
365 | } |
||
366 | |||
367 | /** |
||
368 | * Sets an inherited user property, which cannot be overwritten by set/unset |
||
369 | * property calls. Any previous value is overwritten. Also marks |
||
370 | * these properties as properties that have not come from the |
||
371 | * command line. |
||
372 | * |
||
373 | * @param string $ns the namespace for the property (currently not used) |
||
374 | * @param string $name the name of property to set |
||
375 | * @param string $value the new value of the property |
||
376 | */ |
||
377 | 24 | public function setInheritedProperty($ns, string $name, string $value): void |
|
378 | { |
||
379 | 24 | if (null === $name || null === $value) { |
|
0 ignored issues
–
show
|
|||
380 | return; |
||
381 | } |
||
382 | 24 | $this->inheritedProperties[$name] = $value; |
|
383 | |||
384 | 24 | $this->project->log( |
|
385 | 24 | 'Setting ro project property: ' . $name . ' -> ' |
|
386 | 24 | . $value, |
|
387 | 24 | Project::MSG_DEBUG |
|
388 | 24 | ); |
|
389 | 24 | $this->userProperties[$name] = $value; |
|
390 | |||
391 | 24 | $done = $this->setPropertyHook($ns, $name, $value, true, false, false); |
|
392 | 24 | if ($done) { |
|
393 | return; |
||
394 | } |
||
395 | 24 | $this->properties[$name] = $value; |
|
396 | 24 | $this->project->addReference($name, new PropertyValue($value)); |
|
397 | } |
||
398 | |||
399 | // -------------------- Getting properties -------------------- |
||
400 | |||
401 | /** |
||
402 | * Returns the value of a property, if it is set. You can override |
||
403 | * this method in order to plug your own storage. |
||
404 | * |
||
405 | * @param string $ns the namespace for the property (currently not used) |
||
406 | * @param null|string $name The name of the property. |
||
407 | * May be <code>null</code>, in which case |
||
408 | * the return value is also <code>null</code>. |
||
409 | * |
||
410 | * @return mixed the property value, or <code>null</code> for no match |
||
411 | * or if a <code>null</code> name is provided |
||
412 | */ |
||
413 | 907 | public function getProperty($ns, ?string $name) |
|
414 | { |
||
415 | 907 | if (null === $name) { |
|
416 | return null; |
||
417 | } |
||
418 | 907 | $o = $this->getPropertyHook($ns, $name, false); |
|
419 | 907 | if (null !== $o) { |
|
420 | 1 | return $o; |
|
421 | } |
||
422 | |||
423 | 907 | $found = $this->properties[$name] ?? null; |
|
424 | // check to see if there are unresolved property references |
||
425 | 907 | if (null !== $found && false !== strpos($found, '${')) { |
|
426 | // attempt to resolve properties |
||
427 | 1 | $found = $this->replaceProperties($found, null); |
|
428 | 1 | if (StringHelper::startsWith('${', $found) && StringHelper::endsWith('}', $found)) { |
|
429 | 1 | $found = null; |
|
430 | } |
||
431 | // save resolved value |
||
432 | 1 | $this->properties[$name] = $found; |
|
433 | } |
||
434 | |||
435 | 907 | return $found; |
|
436 | } |
||
437 | |||
438 | /** |
||
439 | * Returns the value of a user property, if it is set. |
||
440 | * |
||
441 | * @param string $ns the namespace for the property (currently not used) |
||
442 | * @param null|string $name The name of the property. |
||
443 | * May be <code>null</code>, in which case |
||
444 | * the return value is also <code>null</code>. |
||
445 | * |
||
446 | * @return null|string the property value, or <code>null</code> for no match |
||
447 | * or if a <code>null</code> name is provided |
||
448 | */ |
||
449 | 13 | public function getUserProperty($ns, ?string $name): ?string |
|
450 | { |
||
451 | 13 | if (null === $name) { |
|
452 | return null; |
||
453 | } |
||
454 | 13 | $o = $this->getPropertyHook($ns, $name, true); |
|
455 | 13 | if (null !== $o) { |
|
456 | return $o; |
||
457 | } |
||
458 | |||
459 | 13 | return $this->userProperties[$name] ?? null; |
|
460 | } |
||
461 | |||
462 | // -------------------- Access to property tables -------------------- |
||
463 | // This is used to support ant call and similar tasks. It should be |
||
464 | // deprecated, it is possible to use a better (more efficient) |
||
465 | // mechanism to preserve the context. |
||
466 | |||
467 | /** |
||
468 | * Returns a copy of the properties table. |
||
469 | * |
||
470 | * @return array a hashtable containing all properties |
||
471 | * (including user properties) |
||
472 | */ |
||
473 | 907 | public function getProperties(): array |
|
474 | { |
||
475 | 907 | return $this->properties; |
|
476 | } |
||
477 | |||
478 | /** |
||
479 | * Returns a copy of the user property hashtable. |
||
480 | * |
||
481 | * @return array a hashtable containing just the user properties |
||
482 | */ |
||
483 | public function getUserProperties(): array |
||
484 | { |
||
485 | return $this->userProperties; |
||
486 | } |
||
487 | |||
488 | public function getInheritedProperties(): array |
||
489 | { |
||
490 | return $this->inheritedProperties; |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * Copies all user properties that have not been set on the |
||
495 | * command line or a GUI tool from this instance to the Project |
||
496 | * instance given as the argument. |
||
497 | * |
||
498 | * <p>To copy all "user" properties, you will also have to call |
||
499 | * {@link #copyUserProperties copyUserProperties}.</p> |
||
500 | * |
||
501 | * @param Project $other the project to copy the properties to. Must not be null. |
||
502 | */ |
||
503 | public function copyInheritedProperties(Project $other): void |
||
504 | { |
||
505 | foreach ($this->inheritedProperties as $arg => $value) { |
||
506 | if (null === $other->getUserProperty($arg)) { |
||
507 | $other->setInheritedProperty($arg, (string) $this->inheritedProperties[$arg]); |
||
508 | } |
||
509 | } |
||
510 | } |
||
511 | |||
512 | /** |
||
513 | * Copies all user properties that have been set on the command |
||
514 | * line or a GUI tool from this instance to the Project instance |
||
515 | * given as the argument. |
||
516 | * |
||
517 | * <p>To copy all "user" properties, you will also have to call |
||
518 | * {@link #copyInheritedProperties copyInheritedProperties}.</p> |
||
519 | * |
||
520 | * @param Project $other the project to copy the properties to |
||
521 | */ |
||
522 | 37 | public function copyUserProperties(Project $other): void |
|
523 | { |
||
524 | 37 | foreach ($this->userProperties as $arg => $value) { |
|
525 | 37 | if (!isset($this->inheritedProperties[$arg])) { |
|
526 | 37 | $other->setUserProperty($arg, $value); |
|
527 | } |
||
528 | } |
||
529 | } |
||
530 | |||
531 | /** |
||
532 | * Parses a string containing <code>${xxx}</code> style property |
||
533 | * references into two lists. The first list is a collection |
||
534 | * of text fragments, while the other is a set of string property names. |
||
535 | * <code>null</code> entries in the first list indicate a property |
||
536 | * reference from the second list. |
||
537 | * |
||
538 | * It can be overridden with a more efficient or customized version. |
||
539 | * |
||
540 | * @param string $value text to parse |
||
541 | * @param array $fragments list to add text fragments to |
||
542 | * @param array $propertyRefs list to add property names to |
||
543 | * |
||
544 | * @throws BuildException if the string contains an opening |
||
545 | * <code>${</code> without a closing |
||
546 | * <code>}</code> |
||
547 | */ |
||
548 | 21 | public function parsePropertyString(string $value, array &$fragments, array &$propertyRefs): void |
|
549 | { |
||
550 | 21 | $prev = 0; |
|
551 | |||
552 | 21 | while (($pos = strpos($value, '$', $prev)) !== false) { |
|
553 | 9 | if ($pos > $prev) { |
|
554 | 7 | $fragments[] = StringHelper::substring($value, $prev, $pos - 1); |
|
555 | } |
||
556 | 9 | if ($pos === (strlen($value) - 1)) { |
|
557 | $fragments[] = '$'; |
||
558 | $prev = $pos + 1; |
||
559 | 9 | } elseif ('{' !== $value[$pos + 1]) { |
|
560 | // the string positions were changed to value-1 to correct |
||
561 | // a fatal error coming from function substring() |
||
562 | $fragments[] = StringHelper::substring($value, $pos, $pos + 1); |
||
563 | $prev = $pos + 2; |
||
564 | } else { |
||
565 | 9 | $endName = strpos($value, '}', $pos); |
|
566 | 9 | if (false === $endName) { |
|
567 | throw new BuildException("Syntax error in property: {$value}"); |
||
568 | } |
||
569 | 9 | $propertyName = StringHelper::substring($value, $pos + 2, $endName - 1); |
|
570 | 9 | $fragments[] = null; |
|
571 | 9 | $propertyRefs[] = $propertyName; |
|
572 | 9 | $prev = $endName + 1; |
|
573 | } |
||
574 | } |
||
575 | |||
576 | 21 | if ($prev < strlen($value)) { |
|
577 | 21 | $fragments[] = StringHelper::substring($value, $prev); |
|
578 | } |
||
579 | } |
||
580 | |||
581 | // -------------------- Hook management -------------------- |
||
582 | |||
583 | /** |
||
584 | * Set the project for which this helper is performing property resolution. |
||
585 | * |
||
586 | * @param Project $p the project instance |
||
587 | */ |
||
588 | 928 | private function setProject(Project $p): void |
|
589 | { |
||
590 | 928 | $this->project = $p; |
|
591 | } |
||
592 | } |
||
593 |