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

FoldConstantXPathExpressions.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 2.73 KiB


001  <?php
002   
003  /**
004  * @package   s9e\TextFormatter
005  * @copyright Copyright (c) 2010-2022 The s9e authors
006  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
007  */
008  namespace s9e\TextFormatter\Configurator\TemplateNormalizations;
009   
010  use Exception;
011  use s9e\TextFormatter\Utils\XPath;
012   
013  class FoldConstantXPathExpressions extends AbstractConstantFolding
014  {
015      /**
016      * @var string[] List of supported XPath functions
017      */
018      protected $supportedFunctions = [
019          'boolean',
020          'ceiling',
021          'concat',
022          'contains',
023          'floor',
024          'normalize-space',
025          'not',
026          'number',
027          'round',
028          'starts-with',
029          'string',
030          'string-length',
031          'substring',
032          'substring-after',
033          'substring-before',
034          'translate'
035      ];
036   
037      /**
038      * {@inheritdoc}
039      */
040      protected function getOptimizationPasses()
041      {
042          return [
043              '(^(?:"[^"]*"|\'[^\']*\'|\\.[0-9]|[^"$&\'./:@[\\]])++$)' => 'foldConstantXPathExpression'
044          ];
045      }
046   
047      /**
048      * Evaluate given expression without raising any warnings
049      *
050      * @param  string $expr
051      * @return mixed
052      */
053      protected function evaluate($expr)
054      {
055          $useErrors = libxml_use_internal_errors(true);
056          $result    = $this->xpath->evaluate($expr);
057          libxml_use_internal_errors($useErrors);
058   
059          return $result;
060      }
061   
062      /**
063      * Evaluate and replace a constant XPath expression
064      *
065      * @param  array  $m
066      * @return string
067      */
068      protected function foldConstantXPathExpression(array $m)
069      {
070          $expr = $m[0];
071          if ($this->isConstantExpression($expr))
072          {
073              try
074              {
075                  $result     = $this->evaluate($expr);
076                  $foldedExpr = XPath::export($result);
077                  $expr       = $this->selectReplacement($expr, $foldedExpr);
078              }
079              catch (Exception $e)
080              {
081                  // Do nothing
082              }
083          }
084   
085          return $expr;
086      }
087   
088      /**
089      * Test whether given expression seems to be constant
090      *
091      * @param  string $expr
092      * @return bool
093      */
094      protected function isConstantExpression($expr)
095      {
096          // Replace strings to avoid false-positives
097          $expr = preg_replace('("[^"]*"|\'[^\']*\')', '0', $expr);
098   
099          // Match function calls against the list of supported functions
100          preg_match_all('(\\w[-\\w]+(?=\\())', $expr, $m);
101          if (count(array_diff($m[0], $this->supportedFunctions)) > 0)
102          {
103              return false;
104          }
105   
106          // Match unsupported characters and keywords, as well as function calls without arguments
107          return !preg_match('([^\\s!\\-0-9<=>a-z\\(-.]|\\.(?![0-9])|\\b[-a-z](?![-\\w]+\\()|\\(\\s*\\))i', $expr);
108      }
109   
110      /**
111      * Select the best replacement for given expression
112      *
113      * @param  string $expr       Original expression
114      * @param  string $foldedExpr Folded expression
115      * @return string
116      */
117      protected function selectReplacement($expr, $foldedExpr)
118      {
119          // Use the folded expression if it's smaller or it's a boolean
120          if (strlen($foldedExpr) < strlen($expr) || $foldedExpr === 'false()' || $foldedExpr === 'true()')
121          {
122              return $foldedExpr;
123          }
124   
125          return $expr;
126      }
127  }