[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 namespace enshrined\svgSanitize\ElementReference; 3 4 use enshrined\svgSanitize\data\XPath; 5 use enshrined\svgSanitize\Exceptions\NestingException; 6 use enshrined\svgSanitize\Helper; 7 8 class Resolver 9 { 10 /** 11 * @var XPath 12 */ 13 protected $xPath; 14 15 /** 16 * @var Subject[] 17 */ 18 protected $subjects = []; 19 20 /** 21 * @var array DOMElement[] 22 */ 23 protected $elementsToRemove = []; 24 25 /** 26 * @var int 27 */ 28 protected $useNestingLimit; 29 30 public function __construct(XPath $xPath, $useNestingLimit) 31 { 32 $this->xPath = $xPath; 33 $this->useNestingLimit = $useNestingLimit; 34 } 35 36 public function collect() 37 { 38 $this->collectIdentifiedElements(); 39 $this->processReferences(); 40 $this->determineInvalidSubjects(); 41 } 42 43 /** 44 * Resolves one subject by element. 45 * 46 * @param \DOMElement $element 47 * @param bool $considerChildren Whether to search in Subject's children as well 48 * @return Subject|null 49 */ 50 public function findByElement(\DOMElement $element, $considerChildren = false) 51 { 52 foreach ($this->subjects as $subject) { 53 if ( 54 $element === $subject->getElement() 55 || $considerChildren && Helper::isElementContainedIn($element, $subject->getElement()) 56 ) { 57 return $subject; 58 } 59 } 60 return null; 61 } 62 63 /** 64 * Resolves subjects (plural!) by element id - in theory malformed 65 * DOM might have same ids assigned to different elements and leaving 66 * it to client/browser implementation which element to actually use. 67 * 68 * @param string $elementId 69 * @return Subject[] 70 */ 71 public function findByElementId($elementId) 72 { 73 return array_filter( 74 $this->subjects, 75 function (Subject $subject) use ($elementId) { 76 return $elementId === $subject->getElementId(); 77 } 78 ); 79 } 80 81 /** 82 * Collects elements having `id` attribute (those that can be referenced). 83 */ 84 protected function collectIdentifiedElements() 85 { 86 /** @var \DOMNodeList|\DOMElement[] $elements */ 87 $elements = $this->xPath->query('//*[@id]'); 88 foreach ($elements as $element) { 89 $this->subjects[$element->getAttribute('id')] = new Subject($element, $this->useNestingLimit); 90 } 91 } 92 93 /** 94 * Processes references from and to elements having `id` attribute concerning 95 * their occurrence in `<use ... xlink:href="#identifier">` statements. 96 */ 97 protected function processReferences() 98 { 99 $useNodeName = $this->xPath->createNodeName('use'); 100 foreach ($this->subjects as $subject) { 101 $useElements = $this->xPath->query( 102 $useNodeName . '[@href or @xlink:href]', 103 $subject->getElement() 104 ); 105 106 /** @var \DOMElement $useElement */ 107 foreach ($useElements as $useElement) { 108 $useId = Helper::extractIdReferenceFromHref( 109 Helper::getElementHref($useElement) 110 ); 111 if ($useId === null || !isset($this->subjects[$useId])) { 112 continue; 113 } 114 $subject->addUse($this->subjects[$useId]); 115 $this->subjects[$useId]->addUsedIn($subject); 116 } 117 } 118 } 119 120 /** 121 * Determines and tags infinite loops. 122 */ 123 protected function determineInvalidSubjects() 124 { 125 foreach ($this->subjects as $subject) { 126 127 if (in_array($subject->getElement(), $this->elementsToRemove)) { 128 continue; 129 } 130 131 $useId = Helper::extractIdReferenceFromHref( 132 Helper::getElementHref($subject->getElement()) 133 ); 134 135 try { 136 if ($useId === $subject->getElementId()) { 137 $this->markSubjectAsInvalid($subject); 138 } elseif ($subject->hasInfiniteLoop()) { 139 $this->markSubjectAsInvalid($subject); 140 } 141 } catch (NestingException $e) { 142 $this->elementsToRemove[] = $e->getElement(); 143 $this->markSubjectAsInvalid($subject); 144 } 145 } 146 } 147 148 /** 149 * Get all the elements that caused a nesting exception. 150 * 151 * @return array 152 */ 153 public function getElementsToRemove() { 154 return $this->elementsToRemove; 155 } 156 157 /** 158 * The Subject is invalid for some reason, therefore we should 159 * remove it and all it's child usages. 160 * 161 * @param Subject $subject 162 */ 163 protected function markSubjectAsInvalid(Subject $subject) { 164 $this->elementsToRemove = array_merge( 165 $this->elementsToRemove, 166 $subject->clearInternalAndGetAffectedElements() 167 ); 168 } 169 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |