ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Resolver.php
Go to the documentation of this file.
1 <?php
3 
7 
8 class Resolver
9 {
13  protected $xPath;
14 
18  protected $subjects = [];
19 
23  protected $elementsToRemove = [];
24 
28  protected $useNestingLimit;
29 
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 
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 
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 
84  protected function collectIdentifiedElements()
85  {
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 
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 
107  foreach ($useElements as $useElement) {
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 
123  protected function determineInvalidSubjects()
124  {
125  foreach ($this->subjects as $subject) {
126 
127  if (in_array($subject->getElement(), $this->elementsToRemove)) {
128  continue;
129  }
130 
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 
153  public function getElementsToRemove() {
155  }
156 
163  protected function markSubjectAsInvalid(Subject $subject) {
164  $this->elementsToRemove = array_merge(
165  $this->elementsToRemove,
167  );
168  }
169 }
static getElementHref(\DOMElement $element)
Definition: Helper.php:10
static extractIdReferenceFromHref($href)
Definition: Helper.php:25
markSubjectAsInvalid(Subject $subject)
The Subject is invalid for some reason, therefore we should remove it and all it&#39;s child usages...
Definition: Resolver.php:163
getElementsToRemove()
Get all the elements that caused a nesting exception.
Definition: Resolver.php:153
static isElementContainedIn(\DOMElement $needle, \DOMElement $haystack)
Definition: Helper.php:38
findByElementId($elementId)
Resolves subjects (plural!) by element id - in theory malformed DOM might have same ids assigned to d...
Definition: Resolver.php:71
determineInvalidSubjects()
Determines and tags infinite loops.
Definition: Resolver.php:123
clearInternalAndGetAffectedElements()
Clear the internal arrays (to free up memory as they can get big) and return all the child usages DOM...
Definition: Subject.php:142
findByElement(\DOMElement $element, $considerChildren=false)
Resolves one subject by element.
Definition: Resolver.php:50
__construct(XPath $xPath, $useNestingLimit)
Definition: Resolver.php:30
getElement()
Get the element that caused the exception.