Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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: 01.05.2026, 11:28 - 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  }