[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/enshrined/svg-sanitize/src/ElementReference/ -> Resolver.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer