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

bbcode_merger.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 5.84 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\textformatter\s9e;
015   
016  use phpbb\textformatter\s9e\factory;
017  use s9e\TextFormatter\Configurator\Helpers\TemplateLoader;
018  use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
019   
020  class bbcode_merger
021  {
022      /**
023      * @var \s9e\TextFormatter\Configurator $configurator Configurator instance used to inspect BBCodes
024      */
025      protected $configurator;
026   
027      /**
028      * @param factory $factory
029      */
030      public function __construct(factory $factory)
031      {
032          $this->configurator = $factory->get_configurator();
033      }
034   
035      /**
036      * Merge two BBCode definitions
037      *
038      * All of the arrays contain a "usage" element and a "template" element
039      *
040      * @throws InvalidArgumentException if a definition cannot be interpreted
041      * @throws RuntimeException if something unexpected occurs
042      *
043      * @param  array $without BBCode definition without an attribute
044      * @param  array $with    BBCode definition with an attribute
045      * @return array          Merged definition
046      */
047      public function merge_bbcodes(array $without, array $with)
048      {
049          $without = $this->create_bbcode($without);
050          $with    = $this->create_bbcode($with);
051   
052          // Select the appropriate strategy for merging this BBCode
053          if (!$this->is_optional_bbcode($without, $with) && $this->is_content_bbcode($without, $with))
054          {
055              $merged = $this->merge_content_bbcode($without, $with);
056          }
057          else
058          {
059              $merged = $this->merge_optional_bbcode($without, $with);
060          }
061   
062          $merged['template'] = $this->normalize_template($merged['template']);
063   
064          return $merged;
065      }
066   
067      /**
068      * Create a custom BBCode for inspection
069      *
070      * @param  array $definition Original BBCode definition
071      * @return array             Updated definition containing a BBCode object and a Tag
072      */
073      protected function create_bbcode(array $definition)
074      {
075          $bbcode = $this->configurator->BBCodes->addCustom(
076              $definition['usage'],
077              new UnsafeTemplate($definition['template'])
078          );
079   
080          $definition['bbcode'] = $bbcode;
081          $definition['tag']    = $this->configurator->tags[$bbcode->tagName];
082   
083          return $definition;
084      }
085   
086      /**
087      * Indent given template for readability
088      *
089      * @param  string $template
090      * @return string
091      */
092      protected function indent_template($template)
093      {
094          $dom = TemplateLoader::load($template);
095          $dom->formatOutput = true;
096          $template = TemplateLoader::save($dom);
097   
098          // Remove the first level of indentation if the template starts with whitespace
099          if (preg_match('(^\\n +)', $template, $m))
100          {
101              $template = str_replace($m[0], "\n", $template);
102          }
103   
104          return trim($template);
105      }
106   
107      /**
108      * Test whether the two definitions form a "content"-style BBCode
109      *
110      * Such BBCodes include the [url] BBCode, which uses its text content as
111      * attribute if none is provided
112      *
113      * @param  array $without BBCode definition without an attribute
114      * @param  array $with    BBCode definition with an attribute
115      * @return bool
116      */
117      protected function is_content_bbcode(array $without, array $with)
118      {
119          // Test whether we find the same non-TEXT token between "]" and "[" in the usage
120          // as between ">" and "<" in the template
121          return (preg_match('(\\]\\s*(\\{(?!TEXT)[^}]+\\})\\s*\\[)', $without['usage'], $m)
122              && preg_match('(>[^<]*?' . preg_quote($m[1]) . '[^>]*?<)s', $without['template']));
123      }
124   
125      /**
126      * Test whether the two definitions form BBCode with an optional attribute
127      *
128      * @param  array $without BBCode definition without an attribute
129      * @param  array $with    BBCode definition with an attribute
130      * @return bool
131      */
132      protected function is_optional_bbcode(array $without, array $with)
133      {
134          // Remove the default attribute from the definition
135          $with['usage'] = preg_replace('(=[^\\]]++)', '', $with['usage']);
136   
137          // Test whether both definitions are the same, regardless of case
138          return strcasecmp($without['usage'], $with['usage']) === 0;
139      }
140   
141      /**
142      * Merge the two BBCode definitions of a "content"-style BBCode
143      *
144      * @param  array $without BBCode definition without an attribute
145      * @param  array $with    BBCode definition with an attribute
146      * @return array          Merged definition
147      */
148      protected function merge_content_bbcode(array $without, array $with)
149      {
150          // Convert [x={X}] into [x={X;useContent}]
151          $usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1);
152   
153          // Use the template from the definition that uses an attribute
154          $template = $with['tag']->template;
155   
156          return ['usage' => $usage, 'template' => $template];
157      }
158   
159      /**
160      * Merge the two BBCode definitions of a BBCode with an optional argument
161      *
162      * Such BBCodes include the [quote] BBCode, which takes an optional argument
163      * but otherwise does not behave differently
164      *
165      * @param  array $without BBCode definition without an attribute
166      * @param  array $with    BBCode definition with an attribute
167      * @return array          Merged definition
168      */
169      protected function merge_optional_bbcode(array $without, array $with)
170      {
171          // Convert [X={X}] into [X={X?}]
172          $usage = preg_replace('(\\})', '?}', $with['usage'], 1);
173   
174          // Build a template for both versions
175          $template = '<xsl:choose><xsl:when test="@' . $with['bbcode']->defaultAttribute . '">' . $with['tag']->template . '</xsl:when><xsl:otherwise>' . $without['tag']->template . '</xsl:otherwise></xsl:choose>';
176   
177          return ['usage' => $usage, 'template' => $template];
178      }
179   
180      /**
181      * Normalize a template
182      *
183      * @param  string $template
184      * @return string
185      */
186      protected function normalize_template($template)
187      {
188          // Normalize the template to simplify it
189          $template = $this->configurator->templateNormalizer->normalizeTemplate($template);
190   
191          // Convert xsl:value-of elements back to {L_} tokens where applicable
192          $template = preg_replace('(<xsl:value-of select="\\$(L_\\w+)"/>)', '{$1}', $template);
193   
194          // Beautify the template
195          $template = $this->indent_template($template);
196   
197          return $template;
198      }
199  }
200