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

XPathConvertor.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 6.30 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\RendererGenerators\PHP;
009   
010  use RuntimeException;
011  use s9e\TextFormatter\Configurator\RecursiveParser;
012  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\BooleanFunctions;
013  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\BooleanOperators;
014  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Comparisons;
015  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Core;
016  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Math;
017  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\MultiByteStringManipulation;
018  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\PHP80Functions;
019  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\SingleByteStringFunctions;
020  use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\SingleByteStringManipulation;
021   
022  class XPathConvertor
023  {
024      /**
025      * @var array Array of togglable PHP features ("mbstring" and "php80")
026      */
027      public $features;
028   
029      /**
030      * @var RecursiveParser
031      */
032      protected $parser;
033   
034      /**
035      * Constructor
036      */
037      public function __construct(RecursiveParser $parser = null)
038      {
039          $this->features = [
040              'mbstring' => extension_loaded('mbstring'),
041              'php80'    => version_compare(PHP_VERSION, '8.0', '>=')
042          ];
043          if (isset($parser))
044          {
045              $this->parser = $parser;
046          }
047      }
048   
049      /**
050      * Convert an XPath expression (used in a condition) into PHP code
051      *
052      * This method is similar to convertXPath() but it selectively replaces some simple conditions
053      * with the corresponding DOM method for performance reasons
054      *
055      * @param  string $expr XPath expression
056      * @return string       PHP code
057      */
058      public function convertCondition($expr)
059      {
060          // Replace @attr with boolean(@attr) in boolean expressions
061          $expr = preg_replace(
062              '((^|(?<!\\bboolean)\\(\\s*|\\b(?:and|or)\\s*)([\\(\\s]*)([$@][-\\w]+|@\\*)([\\)\\s]*)(?=$|\\s+(?:and|or)))',
063              '$1$2boolean($3)$4',
064              trim($expr)
065          );
066   
067          // Replace not(boolean(@attr)) with not(@attr)
068          $expr = preg_replace(
069              '(not\\(boolean\\(([$@][-\\w]+)\\)\\))',
070              'not($1)',
071              $expr
072          );
073   
074          try
075          {
076              return $this->getParser()->parse($expr)['value'];
077          }
078          catch (RuntimeException $e)
079          {
080              // Do nothing
081          }
082   
083          // If the condition does not seem to contain a relational expression, or start with a
084          // function call, we wrap it inside of a boolean() call
085          if (!preg_match('([=<>]|\\bor\\b|\\band\\b|^[-\\w]+\\s*\\()', $expr))
086          {
087              $expr = 'boolean(' . $expr . ')';
088          }
089   
090          return '$this->xpath->evaluate(' . $this->exportXPath($expr) . ',$node)';
091      }
092   
093      /**
094      * Convert an XPath expression (used as value) into PHP code
095      *
096      * @param  string $expr XPath expression
097      * @return string       PHP code
098      */
099      public function convertXPath($expr)
100      {
101          $expr = trim($expr);
102          try
103          {
104              return $this->getParser()->parse($expr)['value'];
105          }
106          catch (RuntimeException $e)
107          {
108              // Do nothing
109          }
110   
111          // Make sure the expression evaluates as a string
112          if (!preg_match('(^[-\\w]*s(?:late|pace|tring)[-\\w]*\\()', $expr))
113          {
114              $expr = 'string(' . $expr . ')';
115          }
116   
117          return '$this->xpath->evaluate(' . $this->exportXPath($expr) . ',$node)';
118      }
119   
120      /**
121      * Export an XPath expression as PHP with special consideration for XPath variables
122      *
123      * Will return PHP source representing the XPath expression, with special consideration for XPath
124      * variables which are returned as a method call to XPath::export()
125      *
126      * @param  string $expr XPath expression
127      * @return string       PHP representation of the expression
128      */
129      protected function exportXPath($expr)
130      {
131          $phpTokens = [];
132          foreach ($this->tokenizeXPathForExport($expr) as [$type, $content])
133          {
134              $methodName  = 'exportXPath' . $type;
135              $phpTokens[] = $this->$methodName($content);
136          }
137   
138          return implode('.', $phpTokens);
139      }
140   
141      /**
142      * Convert a "current()" XPath expression to its PHP source representation
143      *
144      * @return string
145      */
146      protected function exportXPathCurrent()
147      {
148          return '$node->getNodePath()';
149      }
150   
151      /**
152      * Convert a fragment of an XPath expression to its PHP source representation
153      *
154      * @param  string $fragment
155      * @return string
156      */
157      protected function exportXPathFragment($fragment)
158      {
159          return var_export($fragment, true);
160      }
161   
162      /**
163      * Convert an XSLT parameter to its PHP source representation
164      *
165      * @param  string $param Parameter, including the leading $
166      * @return string
167      */
168      protected function exportXPathParam($param)
169      {
170          $paramName = ltrim($param, '$');
171   
172          return '$this->getParamAsXPath(' . var_export($paramName, true) . ')';
173      }
174   
175      /**
176      * Generate and return the a parser with the default set of matchers
177      *
178      * @return RecursiveParser
179      */
180      protected function getDefaultParser()
181      {
182          $parser     = new RecursiveParser;
183          $matchers   = [];
184          $matchers[] = new SingleByteStringFunctions($parser);
185          $matchers[] = new BooleanFunctions($parser);
186          $matchers[] = new BooleanOperators($parser);
187          $matchers[] = new Comparisons($parser);
188          $matchers[] = new Core($parser);
189          $matchers[] = new Math($parser);
190          if (!empty($this->features['mbstring']))
191          {
192              $matchers[] = new MultiByteStringManipulation($parser);
193          }
194          $matchers[] = new SingleByteStringManipulation($parser);
195          if (!empty($this->features['php80']))
196          {
197              $matchers[] = new PHP80Functions($parser);
198          }
199   
200          $parser->setMatchers($matchers);
201   
202          return $parser;
203      }
204   
205      /**
206      * Return (and if necessary, create) the cached instance of the XPath parser
207      *
208      * @return RecursiveParser
209      */
210      protected function getParser(): RecursiveParser
211      {
212          if (!isset($this->parser))
213          {
214              $this->parser = $this->getDefaultParser();
215          }
216   
217          return $this->parser;
218      }
219   
220      /**
221      * Tokenize an XPath expression for use in PHP
222      *
223      * @param  string $expr XPath expression
224      * @return array
225      */
226      protected function tokenizeXPathForExport($expr)
227      {
228          $tokenExprs = [
229              '(*:Current)\\bcurrent\\(\\)',
230              '(*:Param)\\$\\w+',
231              '(*:Fragment)(?:"[^"]*"|\'[^\']*\'|(?!current\\(\\)|\\$\\w).)++'
232          ];
233          preg_match_all('(' . implode('|', $tokenExprs) . ')s', $expr, $matches, PREG_SET_ORDER);
234   
235          $tokens = [];
236          foreach ($matches as $m)
237          {
238              $tokens[] = [$m['MARK'], $m[0]];
239          }
240   
241          return $tokens;
242      }
243  }