[ Index ] |
PHP Cross Reference of phpBB-3.3.10-deutsch |
[Summary view] [Print] [Text view]
1 <?php declare(strict_types=1); 2 3 /** 4 * @package s9e\SweetDOM 5 * @copyright Copyright (c) 2019-2021 The s9e authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\SweetDOM; 9 10 use BadMethodCallException; 11 use DOMElement; 12 use DOMException; 13 use DOMNode; 14 use DOMNodeList; 15 use DOMText; 16 17 /** 18 * @method self appendElement(string $nodeName, $text = '') 19 * @method self appendElementSibling(string $nodeName, $text = '') 20 * @method DOMText appendText(string $text) 21 * @method DOMText appendTextSibling(string $text) 22 * @method self appendXslApplyTemplates(string $select = null) 23 * @method self appendXslApplyTemplatesSibling(string $select = null) 24 * @method self appendXslAttribute(string $name, string $text = '') 25 * @method self appendXslAttributeSibling(string $name, string $text = '') 26 * @method self appendXslChoose() 27 * @method self appendXslChooseSibling() 28 * @method self appendXslComment(string $text = '') 29 * @method self appendXslCommentSibling(string $text = '') 30 * @method self appendXslCopyOf(string $select) 31 * @method self appendXslCopyOfSibling(string $select) 32 * @method self appendXslIf(string $test, string $text = '') 33 * @method self appendXslIfSibling(string $test, string $text = '') 34 * @method self appendXslOtherwise(string $text = '') 35 * @method self appendXslOtherwiseSibling(string $text = '') 36 * @method self appendXslText(string $text = '') 37 * @method self appendXslTextSibling(string $text = '') 38 * @method self appendXslValueOf(string $select) 39 * @method self appendXslValueOfSibling(string $select) 40 * @method self appendXslVariable(string $name, string $select = null) 41 * @method self appendXslVariableSibling(string $name, string $select = null) 42 * @method self appendXslWhen(string $test, string $text = '') 43 * @method self appendXslWhenSibling(string $test, string $text = '') 44 * @method self prependElement(string $nodeName, $text = '') 45 * @method self prependElementSibling(string $nodeName, $text = '') 46 * @method DOMText prependText(string $text) 47 * @method DOMText prependTextSibling(string $text) 48 * @method self prependXslApplyTemplates(string $select = null) 49 * @method self prependXslApplyTemplatesSibling(string $select = null) 50 * @method self prependXslAttribute(string $name, string $text = '') 51 * @method self prependXslAttributeSibling(string $name, string $text = '') 52 * @method self prependXslChoose() 53 * @method self prependXslChooseSibling() 54 * @method self prependXslComment(string $text = '') 55 * @method self prependXslCommentSibling(string $text = '') 56 * @method self prependXslCopyOf(string $select) 57 * @method self prependXslCopyOfSibling(string $select) 58 * @method self prependXslIf(string $test, string $text = '') 59 * @method self prependXslIfSibling(string $test, string $text = '') 60 * @method self prependXslOtherwise(string $text = '') 61 * @method self prependXslOtherwiseSibling(string $text = '') 62 * @method self prependXslText(string $text = '') 63 * @method self prependXslTextSibling(string $text = '') 64 * @method self prependXslValueOf(string $select) 65 * @method self prependXslValueOfSibling(string $select) 66 * @method self prependXslVariable(string $name, string $select = null) 67 * @method self prependXslVariableSibling(string $name, string $select = null) 68 * @method self prependXslWhen(string $test, string $text = '') 69 * @method self prependXslWhenSibling(string $test, string $text = '') 70 * @property Document $ownerDocument 71 */ 72 class Element extends DOMElement 73 { 74 public function __call(string $name, array $arguments) 75 { 76 $name = strtolower($name); 77 $positions = [ 78 'append' => 'beforeend', 79 'appendsibling' => 'afterend', 80 'prepend' => 'afterbegin', 81 'prependsibling' => 'beforebegin' 82 ]; 83 84 if (preg_match('(^(append|prepend)xsl(\\w+?)(sibling|)$)', $name, $m)) 85 { 86 $localName = $m[2]; 87 $where = $positions[$m[1] . $m[3]]; 88 89 return $this->insertXslElement($where, $localName, $arguments); 90 } 91 if (preg_match('(^(append|prepend)element(sibling|)$)', $name, $m)) 92 { 93 $nodeName = $arguments[0]; 94 $text = $arguments[1] ?? ''; 95 $where = $positions[$m[1] . $m[2]]; 96 97 return $this->insertElement($where, $nodeName, $text); 98 } 99 if (preg_match('(^(append|prepend)text(sibling|)$)', $name, $m)) 100 { 101 $text = $arguments[0]; 102 $where = $positions[$m[1] . $m[2]]; 103 104 return $this->insertText($where, $text); 105 } 106 107 throw new BadMethodCallException; 108 } 109 110 /** 111 * Evaluate and return the result of a given XPath expression using this element as context node 112 * 113 * @param string $expr XPath expression 114 * @return mixed 115 */ 116 public function evaluate(string $expr) 117 { 118 return $this->ownerDocument->evaluate($expr, $this); 119 } 120 121 /** 122 * Evaluate and return the first element of a given XPath query using this element as context node 123 * 124 * @param string $expr XPath expression 125 * @return DOMNode|null 126 */ 127 public function firstOf(string $expr): ?DOMNode 128 { 129 return $this->ownerDocument->firstOf($expr, $this); 130 } 131 132 /** 133 * Insert given element relative to this element's position 134 * 135 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 136 * @param self $element 137 * @return self 138 */ 139 public function insertAdjacentElement(string $where, self $element): self 140 { 141 $this->insertAdjacentNode($where, $element); 142 143 return $element; 144 } 145 146 /** 147 * Insert given text relative to this element's position 148 * 149 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 150 * @param string $text 151 * @return void 152 */ 153 public function insertAdjacentText(string $where, string $text): void 154 { 155 $this->insertText($where, $text); 156 } 157 158 /** 159 * Insert given XML relative to this element's position 160 * 161 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 162 * @param string $xml 163 * @return void 164 */ 165 public function insertAdjacentXML(string $where, string $xml): void 166 { 167 $fragment = $this->ownerDocument->createDocumentFragment(); 168 $fragment->appendXML($this->addMissingNamespaceDeclarations($xml)); 169 170 $this->insertAdjacentNode($where, $fragment); 171 } 172 173 /** 174 * Evaluate and return the result of a given XPath query using this element as context node 175 * 176 * @param string $expr XPath expression 177 * @return DOMNodeList 178 */ 179 public function query(string $expr): DOMNodeList 180 { 181 return $this->ownerDocument->query($expr, $this); 182 } 183 184 /** 185 * Remove this element from the document 186 * 187 * @return void 188 */ 189 public function remove(): void 190 { 191 $this->parentOrThrow()->removeChild($this); 192 } 193 194 /** 195 * Replace this element with given nodes/text 196 * 197 * @param DOMNode|string $nodes 198 * @return void 199 */ 200 public function replaceWith(...$nodes): void 201 { 202 $parentNode = $this->parentOrThrow(new DOMException('No Modification Allowed Error', DOM_NO_MODIFICATION_ALLOWED_ERR)); 203 204 foreach ($nodes as $node) 205 { 206 if (!($node instanceof DOMNode)) 207 { 208 $node = $this->ownerDocument->createTextNode((string) $node); 209 } 210 $parentNode->insertBefore($node, $this); 211 } 212 $parentNode->removeChild($this); 213 } 214 215 /** 216 * Add namespace declarations that may be missing in given XML 217 * 218 * @param string $xml Original XML 219 * @return string Modified XML 220 */ 221 protected function addMissingNamespaceDeclarations(string $xml): string 222 { 223 preg_match_all('(xmlns:\\K[-\\w]++(?==))', $xml, $m); 224 $prefixes = array_flip($m[0]); 225 226 return preg_replace_callback( 227 '(<([-\\w]++):[^>]*?\\K\\s*/?>)', 228 function ($m) use ($prefixes) 229 { 230 $return = $m[0]; 231 $prefix = $m[1]; 232 if (!isset($prefixes[$prefix])) 233 { 234 $nsURI = $this->lookupNamespaceURI($prefix); 235 $return = ' xmlns:' . $prefix . '="' . htmlspecialchars($nsURI, ENT_XML1) . '"' . $return; 236 } 237 238 return $return; 239 }, 240 $xml 241 ); 242 } 243 244 /** 245 * Insert given node relative to this element's position 246 * 247 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 248 * @param DOMNode $node 249 * @return void 250 */ 251 protected function insertAdjacentNode(string $where, DOMNode $node): void 252 { 253 switch (strtolower($where)) 254 { 255 case 'afterbegin': 256 $this->insertBefore($node, $this->firstChild); 257 break; 258 259 case 'afterend': 260 if (isset($this->parentNode)) 261 { 262 $this->parentNode->insertBefore($node, $this->nextSibling); 263 } 264 break; 265 266 case 'beforebegin': 267 if (isset($this->parentNode)) 268 { 269 $this->parentNode->insertBefore($node, $this); 270 } 271 break; 272 273 case 'beforeend': 274 $this->appendChild($node); 275 break; 276 277 default: 278 throw new DOMException("'$where' is not one of 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'", DOM_SYNTAX_ERR); 279 } 280 } 281 282 /** 283 * Create and insert an element at given position 284 * 285 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 286 * @param string $nodeName Element's nodeName 287 * @param string $text Text content 288 * @return self 289 */ 290 protected function insertElement(string $where, string $nodeName, string $text): self 291 { 292 $text = htmlspecialchars($text, ENT_NOQUOTES); 293 $pos = strpos($nodeName, ':'); 294 if ($pos === false) 295 { 296 $element = $this->ownerDocument->createElement($nodeName, $text); 297 } 298 else 299 { 300 $prefix = substr($nodeName, 0, $pos); 301 $namespaceURI = $this->ownerDocument->lookupNamespaceURI($prefix); 302 $element = $this->ownerDocument->createElementNS($namespaceURI, $nodeName, $text); 303 } 304 305 return $this->insertAdjacentElement($where, $element); 306 } 307 308 /** 309 * Insert given text relative to this element's position 310 * 311 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 312 * @param string $text 313 * @return DOMText 314 */ 315 protected function insertText(string $where, string $text): DOMText 316 { 317 $node = $this->ownerDocument->createTextNode($text); 318 $this->insertAdjacentNode($where, $node); 319 320 return $node; 321 } 322 323 /** 324 * Create and insert an XSL element at given position 325 * 326 * @param string $where One of 'beforebegin', 'afterbegin', 'beforeend', 'afterend' 327 * @param string $localName Element's localName 328 * @param array $arguments Arguments passed to the Document::create* function 329 * @return self 330 */ 331 protected function insertXslElement(string $where, string $localName, array $arguments): self 332 { 333 $callback = [$this->ownerDocument, 'createXsl' . ucfirst($localName)]; 334 if (!is_callable($callback)) 335 { 336 throw new BadMethodCallException; 337 } 338 339 $element = call_user_func_array($callback, $arguments); 340 341 return $this->insertAdjacentElement($where, $element); 342 } 343 344 /** 345 * Return this element's parent element if available, or throw an exception 346 * 347 * @param DOMException $previous Previous exception 348 * @return DOMNode 349 */ 350 protected function parentOrThrow(DOMException $previous = null): DOMNode 351 { 352 if (isset($this->parentNode)) 353 { 354 return $this->parentNode; 355 } 356 357 throw new DOMException('Not Found Error', DOM_NOT_FOUND_ERR, $previous); 358 } 359 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Feb 22 20:16:20 2023 | Cross-referenced by PHPXref 0.7.1 |