Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ExtensionSet.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 12.58 KiB


001  <?php
002   
003  /*
004   * This file is part of Twig.
005   *
006   * (c) Fabien Potencier
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Twig;
013   
014  use Twig\Error\RuntimeError;
015  use Twig\Extension\ExtensionInterface;
016  use Twig\Extension\GlobalsInterface;
017  use Twig\Extension\InitRuntimeInterface;
018  use Twig\Extension\StagingExtension;
019  use Twig\NodeVisitor\NodeVisitorInterface;
020  use Twig\TokenParser\TokenParserInterface;
021   
022  /**
023   * @author Fabien Potencier <fabien@symfony.com>
024   *
025   * @internal
026   */
027  final class ExtensionSet
028  {
029      private $extensions;
030      private $initialized = false;
031      private $runtimeInitialized = false;
032      private $staging;
033      private $parsers;
034      private $visitors;
035      private $filters;
036      private $tests;
037      private $functions;
038      private $unaryOperators;
039      private $binaryOperators;
040      private $globals;
041      private $functionCallbacks = [];
042      private $filterCallbacks = [];
043      private $lastModified = 0;
044   
045      public function __construct()
046      {
047          $this->staging = new StagingExtension();
048      }
049   
050      /**
051       * Initializes the runtime environment.
052       *
053       * @deprecated since Twig 2.7
054       */
055      public function initRuntime(Environment $env)
056      {
057          if ($this->runtimeInitialized) {
058              return;
059          }
060   
061          $this->runtimeInitialized = true;
062   
063          foreach ($this->extensions as $extension) {
064              if ($extension instanceof InitRuntimeInterface) {
065                  $extension->initRuntime($env);
066              }
067          }
068      }
069   
070      public function hasExtension(string $class): bool
071      {
072          $class = ltrim($class, '\\');
073          if (!isset($this->extensions[$class]) && class_exists($class, false)) {
074              // For BC/FC with namespaced aliases
075              $class = (new \ReflectionClass($class))->name;
076          }
077   
078          return isset($this->extensions[$class]);
079      }
080   
081      public function getExtension(string $class): ExtensionInterface
082      {
083          $class = ltrim($class, '\\');
084          if (!isset($this->extensions[$class]) && class_exists($class, false)) {
085              // For BC/FC with namespaced aliases
086              $class = (new \ReflectionClass($class))->name;
087          }
088   
089          if (!isset($this->extensions[$class])) {
090              throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class));
091          }
092   
093          return $this->extensions[$class];
094      }
095   
096      /**
097       * @param ExtensionInterface[] $extensions
098       */
099      public function setExtensions(array $extensions)
100      {
101          foreach ($extensions as $extension) {
102              $this->addExtension($extension);
103          }
104      }
105   
106      /**
107       * @return ExtensionInterface[]
108       */
109      public function getExtensions(): array
110      {
111          return $this->extensions;
112      }
113   
114      public function getSignature(): string
115      {
116          return json_encode(array_keys($this->extensions));
117      }
118   
119      public function isInitialized(): bool
120      {
121          return $this->initialized || $this->runtimeInitialized;
122      }
123   
124      public function getLastModified(): int
125      {
126          if (0 !== $this->lastModified) {
127              return $this->lastModified;
128          }
129   
130          foreach ($this->extensions as $extension) {
131              $r = new \ReflectionObject($extension);
132              if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModified) {
133                  $this->lastModified = $extensionTime;
134              }
135          }
136   
137          return $this->lastModified;
138      }
139   
140      public function addExtension(ExtensionInterface $extension)
141      {
142          $class = \get_class($extension);
143   
144          if ($this->initialized) {
145              throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $class));
146          }
147   
148          if (isset($this->extensions[$class])) {
149              throw new \LogicException(sprintf('Unable to register extension "%s" as it is already registered.', $class));
150          }
151   
152          $this->extensions[$class] = $extension;
153      }
154   
155      public function addFunction(TwigFunction $function)
156      {
157          if ($this->initialized) {
158              throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $function->getName()));
159          }
160   
161          $this->staging->addFunction($function);
162      }
163   
164      /**
165       * @return TwigFunction[]
166       */
167      public function getFunctions(): array
168      {
169          if (!$this->initialized) {
170              $this->initExtensions();
171          }
172   
173          return $this->functions;
174      }
175   
176      /**
177       * @return TwigFunction|false
178       */
179      public function getFunction(string $name)
180      {
181          if (!$this->initialized) {
182              $this->initExtensions();
183          }
184   
185          if (isset($this->functions[$name])) {
186              return $this->functions[$name];
187          }
188   
189          foreach ($this->functions as $pattern => $function) {
190              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
191   
192              if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) {
193                  array_shift($matches);
194                  $function->setArguments($matches);
195   
196                  return $function;
197              }
198          }
199   
200          foreach ($this->functionCallbacks as $callback) {
201              if (false !== $function = $callback($name)) {
202                  return $function;
203              }
204          }
205   
206          return false;
207      }
208   
209      public function registerUndefinedFunctionCallback(callable $callable)
210      {
211          $this->functionCallbacks[] = $callable;
212      }
213   
214      public function addFilter(TwigFilter $filter)
215      {
216          if ($this->initialized) {
217              throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $filter->getName()));
218          }
219   
220          $this->staging->addFilter($filter);
221      }
222   
223      /**
224       * @return TwigFilter[]
225       */
226      public function getFilters(): array
227      {
228          if (!$this->initialized) {
229              $this->initExtensions();
230          }
231   
232          return $this->filters;
233      }
234   
235      /**
236       * @return TwigFilter|false
237       */
238      public function getFilter(string $name)
239      {
240          if (!$this->initialized) {
241              $this->initExtensions();
242          }
243   
244          if (isset($this->filters[$name])) {
245              return $this->filters[$name];
246          }
247   
248          foreach ($this->filters as $pattern => $filter) {
249              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
250   
251              if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) {
252                  array_shift($matches);
253                  $filter->setArguments($matches);
254   
255                  return $filter;
256              }
257          }
258   
259          foreach ($this->filterCallbacks as $callback) {
260              if (false !== $filter = $callback($name)) {
261                  return $filter;
262              }
263          }
264   
265          return false;
266      }
267   
268      public function registerUndefinedFilterCallback(callable $callable)
269      {
270          $this->filterCallbacks[] = $callable;
271      }
272   
273      public function addNodeVisitor(NodeVisitorInterface $visitor)
274      {
275          if ($this->initialized) {
276              throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
277          }
278   
279          $this->staging->addNodeVisitor($visitor);
280      }
281   
282      /**
283       * @return NodeVisitorInterface[]
284       */
285      public function getNodeVisitors(): array
286      {
287          if (!$this->initialized) {
288              $this->initExtensions();
289          }
290   
291          return $this->visitors;
292      }
293   
294      public function addTokenParser(TokenParserInterface $parser)
295      {
296          if ($this->initialized) {
297              throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
298          }
299   
300          $this->staging->addTokenParser($parser);
301      }
302   
303      /**
304       * @return TokenParserInterface[]
305       */
306      public function getTokenParsers(): array
307      {
308          if (!$this->initialized) {
309              $this->initExtensions();
310          }
311   
312          return $this->parsers;
313      }
314   
315      public function getGlobals(): array
316      {
317          if (null !== $this->globals) {
318              return $this->globals;
319          }
320   
321          $globals = [];
322          foreach ($this->extensions as $extension) {
323              if (!$extension instanceof GlobalsInterface) {
324                  continue;
325              }
326   
327              $extGlobals = $extension->getGlobals();
328              if (!\is_array($extGlobals)) {
329                  throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
330              }
331   
332              $globals = array_merge($globals, $extGlobals);
333          }
334   
335          if ($this->initialized) {
336              $this->globals = $globals;
337          }
338   
339          return $globals;
340      }
341   
342      public function addTest(TwigTest $test)
343      {
344          if ($this->initialized) {
345              throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $test->getName()));
346          }
347   
348          $this->staging->addTest($test);
349      }
350   
351      /**
352       * @return TwigTest[]
353       */
354      public function getTests(): array
355      {
356          if (!$this->initialized) {
357              $this->initExtensions();
358          }
359   
360          return $this->tests;
361      }
362   
363      /**
364       * @return TwigTest|false
365       */
366      public function getTest(string $name)
367      {
368          if (!$this->initialized) {
369              $this->initExtensions();
370          }
371   
372          if (isset($this->tests[$name])) {
373              return $this->tests[$name];
374          }
375   
376          foreach ($this->tests as $pattern => $test) {
377              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
378   
379              if ($count) {
380                  if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
381                      array_shift($matches);
382                      $test->setArguments($matches);
383   
384                      return $test;
385                  }
386              }
387          }
388   
389          return false;
390      }
391   
392      public function getUnaryOperators(): array
393      {
394          if (!$this->initialized) {
395              $this->initExtensions();
396          }
397   
398          return $this->unaryOperators;
399      }
400   
401      public function getBinaryOperators(): array
402      {
403          if (!$this->initialized) {
404              $this->initExtensions();
405          }
406   
407          return $this->binaryOperators;
408      }
409   
410      private function initExtensions()
411      {
412          $this->parsers = [];
413          $this->filters = [];
414          $this->functions = [];
415          $this->tests = [];
416          $this->visitors = [];
417          $this->unaryOperators = [];
418          $this->binaryOperators = [];
419   
420          foreach ($this->extensions as $extension) {
421              $this->initExtension($extension);
422          }
423          $this->initExtension($this->staging);
424          // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception
425          $this->initialized = true;
426      }
427   
428      private function initExtension(ExtensionInterface $extension)
429      {
430          // filters
431          foreach ($extension->getFilters() as $filter) {
432              $this->filters[$filter->getName()] = $filter;
433          }
434   
435          // functions
436          foreach ($extension->getFunctions() as $function) {
437              $this->functions[$function->getName()] = $function;
438          }
439   
440          // tests
441          foreach ($extension->getTests() as $test) {
442              $this->tests[$test->getName()] = $test;
443          }
444   
445          // token parsers
446          foreach ($extension->getTokenParsers() as $parser) {
447              if (!$parser instanceof TokenParserInterface) {
448                  throw new \LogicException('getTokenParsers() must return an array of \Twig\TokenParser\TokenParserInterface.');
449              }
450   
451              $this->parsers[] = $parser;
452          }
453   
454          // node visitors
455          foreach ($extension->getNodeVisitors() as $visitor) {
456              $this->visitors[] = $visitor;
457          }
458   
459          // operators
460          if ($operators = $extension->getOperators()) {
461              if (!\is_array($operators)) {
462                  throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators)));
463              }
464   
465              if (2 !== \count($operators)) {
466                  throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
467              }
468   
469              $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
470              $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
471          }
472      }
473  }
474   
475  class_alias('Twig\ExtensionSet', 'Twig_ExtensionSet');
476