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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
FoldConstantXPathExpressions.php
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 }