[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package s9e\TextFormatter 5 * @copyright Copyright (c) 2010-2022 The s9e authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\TextFormatter\Configurator\TemplateNormalizations; 9 10 use Exception; 11 use s9e\TextFormatter\Utils\XPath; 12 13 class FoldConstantXPathExpressions extends AbstractConstantFolding 14 { 15 /** 16 * @var string[] List of supported XPath functions 17 */ 18 protected $supportedFunctions = [ 19 'boolean', 20 'ceiling', 21 'concat', 22 'contains', 23 'floor', 24 'normalize-space', 25 'not', 26 'number', 27 'round', 28 'starts-with', 29 'string', 30 'string-length', 31 'substring', 32 'substring-after', 33 'substring-before', 34 'translate' 35 ]; 36 37 /** 38 * {@inheritdoc} 39 */ 40 protected function getOptimizationPasses() 41 { 42 return [ 43 '(^(?:"[^"]*"|\'[^\']*\'|\\.[0-9]|[^"$&\'./:@[\\]])++$)' => 'foldConstantXPathExpression' 44 ]; 45 } 46 47 /** 48 * Evaluate given expression without raising any warnings 49 * 50 * @param string $expr 51 * @return mixed 52 */ 53 protected function evaluate($expr) 54 { 55 $useErrors = libxml_use_internal_errors(true); 56 $result = $this->xpath->evaluate($expr); 57 libxml_use_internal_errors($useErrors); 58 59 return $result; 60 } 61 62 /** 63 * Evaluate and replace a constant XPath expression 64 * 65 * @param array $m 66 * @return string 67 */ 68 protected function foldConstantXPathExpression(array $m) 69 { 70 $expr = $m[0]; 71 if ($this->isConstantExpression($expr)) 72 { 73 try 74 { 75 $result = $this->evaluate($expr); 76 $foldedExpr = XPath::export($result); 77 $expr = $this->selectReplacement($expr, $foldedExpr); 78 } 79 catch (Exception $e) 80 { 81 // Do nothing 82 } 83 } 84 85 return $expr; 86 } 87 88 /** 89 * Test whether given expression seems to be constant 90 * 91 * @param string $expr 92 * @return bool 93 */ 94 protected function isConstantExpression($expr) 95 { 96 // Replace strings to avoid false-positives 97 $expr = preg_replace('("[^"]*"|\'[^\']*\')', '0', $expr); 98 99 // 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |