PluginProbe
WindPress – Tailwind CSS integration for WordPress / 3.2.90
WindPress – Tailwind CSS integration for WordPress v3.2.90
3.2.90 3.2.89 3.2.88 3.2.87 3.2.86 3.2.85 3.2.84 3.2.83 3.2.82 3.2.81 trunk 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.2 3.0.3 3.0.4 3.0.5 All 144 releases
windpress / vendor / enshrined / svg-sanitize / src / ElementReference / Resolver.php

Resolver.php in WindPress – Tailwind CSS integration for WordPress 3.2.90, at vendor/enshrined/svg-sanitize/src/ElementReference/Resolver.php

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