Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

MergeIdenticalConditionalBranches.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 3.89 KiB


001  <?php
002   
003  /**
004  * @package   s9e\TextFormatter
005  * @copyright Copyright (c) 2010-2022 The s9e authors
006  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
007  */
008  namespace s9e\TextFormatter\Configurator\TemplateNormalizations;
009   
010  use DOMElement;
011  use DOMNode;
012  use s9e\TextFormatter\Configurator\Helpers\XPathHelper;
013   
014  /**
015  * Merge xsl:when branches if they have identical content
016  *
017  * NOTE: may fail if branches have identical equality expressions, e.g. "@a=1" and "@a=1"
018  */
019  class MergeIdenticalConditionalBranches extends AbstractNormalization
020  {
021      /**
022      * {@inheritdoc}
023      */
024      protected $queries = ['//xsl:choose'];
025   
026      /**
027      * Collect consecutive xsl:when elements that share the same kind of equality tests
028      *
029      * Will return xsl:when elements that test a constant part (e.g. a literal) against the same
030      * variable part (e.g. the same attribute)
031      *
032      * @param  DOMNode      $node First node to inspect
033      * @return DOMElement[]
034      */
035      protected function collectCompatibleBranches(DOMNode $node)
036      {
037          $nodes  = [];
038          $key    = null;
039          $values = [];
040   
041          while ($node && $this->isXsl($node, 'when'))
042          {
043              $branch = XPathHelper::parseEqualityExpr($node->getAttribute('test'));
044   
045              if ($branch === false || count($branch) !== 1)
046              {
047                  // The expression is not entirely composed of equalities, or they have a different
048                  // variable part
049                  break;
050              }
051   
052              if (isset($key) && key($branch) !== $key)
053              {
054                  // Not the same variable as our branches
055                  break;
056              }
057   
058              if (array_intersect($values, end($branch)))
059              {
060                  // Duplicate values across branches, e.g. ".=1 or .=2" and ".=2 or .=3"
061                  break;
062              }
063   
064              $key    = key($branch);
065              $values = array_merge($values, end($branch));
066   
067              // Record this node then move on to the next sibling
068              $nodes[] = $node;
069              $node    = $node->nextSibling;
070          }
071   
072          return $nodes;
073      }
074   
075      /**
076      * Merge identical xsl:when elements from a list
077      *
078      * @param  DOMElement[] $nodes
079      * @return void
080      */
081      protected function mergeBranches(array $nodes)
082      {
083          $sortedNodes = [];
084          foreach ($nodes as $node)
085          {
086              $outerXML = $node->ownerDocument->saveXML($node);
087              $innerXML = preg_replace('([^>]+>(.*)<[^<]+)s', '$1', $outerXML);
088   
089              $sortedNodes[$innerXML][] = $node;
090          }
091   
092          foreach ($sortedNodes as $identicalNodes)
093          {
094              if (count($identicalNodes) < 2)
095              {
096                  continue;
097              }
098   
099              $expr = [];
100              foreach ($identicalNodes as $i => $node)
101              {
102                  $expr[] = $node->getAttribute('test');
103   
104                  if ($i > 0)
105                  {
106                      $node->parentNode->removeChild($node);
107                  }
108              }
109   
110              $identicalNodes[0]->setAttribute('test', implode(' or ', $expr));
111          }
112      }
113   
114      /**
115      * Inspect the branches of an xsl:choose element and merge branches if their content is identical
116      * and their order does not matter
117      *
118      * @param  DOMElement $choose xsl:choose element
119      * @return void
120      */
121      protected function mergeCompatibleBranches(DOMElement $choose)
122      {
123          $node = $choose->firstChild;
124          while ($node)
125          {
126              $nodes = $this->collectCompatibleBranches($node);
127   
128              if (count($nodes) > 1)
129              {
130                  $node = end($nodes)->nextSibling;
131   
132                  // Try to merge branches if there's more than one of them
133                  $this->mergeBranches($nodes);
134              }
135              else
136              {
137                  $node = $node->nextSibling;
138              }
139          }
140      }
141   
142      /**
143      * Inspect the branches of an xsl:choose element and merge consecutive branches if their content
144      * is identical
145      *
146      * @param  DOMElement $choose xsl:choose element
147      * @return void
148      */
149      protected function mergeConsecutiveBranches(DOMElement $choose)
150      {
151          // Try to merge consecutive branches even if their test conditions are not compatible,
152          // e.g. "@a=1" and "@b=2"
153          $nodes = [];
154          foreach ($choose->childNodes as $node)
155          {
156              if ($this->isXsl($node, 'when'))
157              {
158                  $nodes[] = $node;
159              }
160          }
161   
162          $i = count($nodes);
163          while (--$i > 0)
164          {
165              $this->mergeBranches([$nodes[$i - 1], $nodes[$i]]);
166          }
167      }
168   
169      /**
170      * {@inheritdoc}
171      */
172      protected function normalizeElement(DOMElement $element)
173      {
174          $this->mergeCompatibleBranches($element);
175          $this->mergeConsecutiveBranches($element);
176      }
177  }