[ 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\RendererGenerators\PHP; 9 10 use RuntimeException; 11 use s9e\TextFormatter\Configurator\RecursiveParser; 12 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\BooleanFunctions; 13 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\BooleanOperators; 14 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Comparisons; 15 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Core; 16 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\Math; 17 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\MultiByteStringManipulation; 18 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\PHP80Functions; 19 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\SingleByteStringFunctions; 20 use s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors\SingleByteStringManipulation; 21 22 class XPathConvertor 23 { 24 /** 25 * @var array Array of togglable PHP features ("mbstring" and "php80") 26 */ 27 public $features; 28 29 /** 30 * @var RecursiveParser 31 */ 32 protected $parser; 33 34 /** 35 * Constructor 36 */ 37 public function __construct(RecursiveParser $parser = null) 38 { 39 $this->features = [ 40 'mbstring' => extension_loaded('mbstring'), 41 'php80' => version_compare(PHP_VERSION, '8.0', '>=') 42 ]; 43 if (isset($parser)) 44 { 45 $this->parser = $parser; 46 } 47 } 48 49 /** 50 * Convert an XPath expression (used in a condition) into PHP code 51 * 52 * This method is similar to convertXPath() but it selectively replaces some simple conditions 53 * with the corresponding DOM method for performance reasons 54 * 55 * @param string $expr XPath expression 56 * @return string PHP code 57 */ 58 public function convertCondition($expr) 59 { 60 // Replace @attr with boolean(@attr) in boolean expressions 61 $expr = preg_replace( 62 '((^|(?<!\\bboolean)\\(\\s*|\\b(?:and|or)\\s*)([\\(\\s]*)([$@][-\\w]+|@\\*)([\\)\\s]*)(?=$|\\s+(?:and|or)))', 63 '$1$2boolean($3)$4', 64 trim($expr) 65 ); 66 67 // Replace not(boolean(@attr)) with not(@attr) 68 $expr = preg_replace( 69 '(not\\(boolean\\(([$@][-\\w]+)\\)\\))', 70 'not($1)', 71 $expr 72 ); 73 74 try 75 { 76 return $this->getParser()->parse($expr)['value']; 77 } 78 catch (RuntimeException $e) 79 { 80 // Do nothing 81 } 82 83 // If the condition does not seem to contain a relational expression, or start with a 84 // function call, we wrap it inside of a boolean() call 85 if (!preg_match('([=<>]|\\bor\\b|\\band\\b|^[-\\w]+\\s*\\()', $expr)) 86 { 87 $expr = 'boolean(' . $expr . ')'; 88 } 89 90 return '$this->xpath->evaluate(' . $this->exportXPath($expr) . ',$node)'; 91 } 92 93 /** 94 * Convert an XPath expression (used as value) into PHP code 95 * 96 * @param string $expr XPath expression 97 * @return string PHP code 98 */ 99 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 }
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 |