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

Configurator.php

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 6.29 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\Plugins\Emoticons;
009   
010  use ArrayAccess;
011  use Countable;
012  use Iterator;
013  use s9e\TextFormatter\Configurator\Helpers\ConfigHelper;
014  use s9e\TextFormatter\Configurator\Helpers\RegexpBuilder;
015  use s9e\TextFormatter\Configurator\Items\Regexp;
016  use s9e\TextFormatter\Configurator\JavaScript\RegexpConvertor;
017  use s9e\TextFormatter\Configurator\Traits\CollectionProxy;
018  use s9e\TextFormatter\Plugins\ConfiguratorBase;
019  use s9e\TextFormatter\Plugins\Emoticons\Configurator\EmoticonCollection;
020  use s9e\TextFormatter\Utils\XPath;
021   
022  /**
023  * @method mixed   add(string $key, mixed $value) Add an item to this collection
024  * @method array   asConfig()
025  * @method void    clear()                        Empty this collection
026  * @method bool    contains(mixed $value)         Test whether a given value is present in this collection
027  * @method integer count()
028  * @method mixed   current()
029  * @method void    delete(string $key)            Delete an item from this collection
030  * @method bool    exists(string $key)            Test whether an item of given key exists
031  * @method mixed   get(string $key)               Return a value from this collection
032  * @method mixed   indexOf(mixed $value)          Find the index of a given value
033  * @method integer|string key()
034  * @method mixed   next()
035  * @method string  normalizeKey(string $key)      Normalize an item's key
036  * @method string  normalizeValue(string $value)  Normalize an emoticon's template
037  * @method bool    offsetExists(string|integer $offset)
038  * @method mixed   offsetGet(string|integer $offset)
039  * @method void    offsetSet(string|integer $offset, mixed $value)
040  * @method void    offsetUnset(string|integer $offset)
041  * @method string  onDuplicate(string|null $action) Query and set the action to take when add() is called with a key that already exists
042  * @method void    rewind()
043  * @method mixed   set(string $key, mixed $value) Set and overwrite a value in this collection
044  * @method bool    valid()
045  */
046  class Configurator extends ConfiguratorBase implements ArrayAccess, Countable, Iterator
047  {
048      use CollectionProxy;
049   
050      /**
051      * @var EmoticonCollection
052      */
053      protected $collection;
054   
055      /**
056      * @var string PCRE subpattern used in a negative lookbehind assertion before the emoticons
057      */
058      public $notAfter = '';
059   
060      /**
061      * @var string PCRE subpattern used in a negative lookahead assertion after the emoticons
062      */
063      public $notBefore = '';
064   
065      /**
066      * @var string XPath expression that, if true, forces emoticons to be rendered as text
067      */
068      public $notIfCondition;
069   
070      /**
071      * {@inheritdoc}
072      */
073      protected $onDuplicateAction = 'replace';
074   
075      /**
076      * @var string Name of the tag used by this plugin
077      */
078      protected $tagName = 'E';
079   
080      /**
081      * Plugin's setup
082      *
083      * Will create the tag used by this plugin
084      */
085      protected function setUp()
086      {
087          $this->collection = new EmoticonCollection;
088   
089          if (!$this->configurator->tags->exists($this->tagName))
090          {
091              $this->configurator->tags->add($this->tagName);
092          }
093      }
094   
095      /**
096      * Create the template used for emoticons
097      *
098      * @return void
099      */
100      public function finalize()
101      {
102          $tag = $this->getTag();
103   
104          if (!isset($tag->template))
105          {
106              $tag->template = $this->getTemplate();
107          }
108      }
109   
110      /**
111      * @return array
112      */
113      public function asConfig()
114      {
115          if (!count($this->collection))
116          {
117              return;
118          }
119   
120          // Grab the emoticons from the collection
121          $codes = array_keys(iterator_to_array($this->collection));
122   
123          // Build the regexp used to match emoticons
124          $regexp = '/';
125   
126          if ($this->notAfter !== '')
127          {
128              $regexp .= '(?<!' . $this->notAfter . ')';
129          }
130   
131          $regexp .= RegexpBuilder::fromList($codes);
132   
133          if ($this->notBefore !== '')
134          {
135              $regexp .= '(?!' . $this->notBefore . ')';
136          }
137   
138          $regexp .= '/S';
139   
140          // Set the Unicode mode if Unicode properties are used
141          if (preg_match('/\\\\[pP](?>\\{\\^?\\w+\\}|\\w\\w?)/', $regexp))
142          {
143              $regexp .= 'u';
144          }
145   
146          // Force the regexp to use atomic grouping for performance
147          $regexp = preg_replace('/(?<!\\\\)((?>\\\\\\\\)*)\\(\\?:/', '$1(?>', $regexp);
148   
149          // Prepare the config array
150          $config = [
151              'quickMatch' => $this->quickMatch,
152              'regexp'     => $regexp,
153              'tagName'    => $this->tagName
154          ];
155   
156          // If notAfter is used, we need to create a JavaScript-specific regexp that does not use a
157          // lookbehind assertion, and we add the notAfter subpattern to the config as a variant
158          if ($this->notAfter !== '')
159          {
160              // Skip the first assertion by skipping the first N characters, where N equals the
161              // length of $this->notAfter plus 1 for the first "/" and 5 for "(?<!)"
162              $lpos = 6 + strlen($this->notAfter);
163              $rpos = strrpos($regexp, '/');
164              $jsRegexp = RegexpConvertor::toJS('/' . substr($regexp, $lpos, $rpos - $lpos) . '/', true);
165   
166              $config['regexp'] = new Regexp($regexp);
167              $config['regexp']->setJS($jsRegexp);
168   
169              $config['notAfter'] = new Regexp('/' . $this->notAfter . '/');
170          }
171   
172          // Try to find a quickMatch if none is set
173          if ($this->quickMatch === false)
174          {
175              $config['quickMatch'] = ConfigHelper::generateQuickMatchFromList($codes);
176          }
177   
178          return $config;
179      }
180   
181      /**
182      * {@inheritdoc}
183      */
184      public function getJSHints()
185      {
186          return ['EMOTICONS_NOT_AFTER' => (int) !empty($this->notAfter)];
187      }
188   
189      /**
190      * Generate the dynamic template that renders all emoticons
191      *
192      * @return string
193      */
194      public function getTemplate()
195      {
196          // Build the <xsl:choose> node
197          $xsl = '<xsl:choose>';
198   
199          // First, test whether the emoticon should be rendered as text if applicable
200          if (!empty($this->notIfCondition))
201          {
202              $xsl .= '<xsl:when test="' . htmlspecialchars($this->notIfCondition, ENT_COMPAT) . '">'
203                    . '<xsl:value-of select="."/>'
204                    . '</xsl:when>'
205                    . '<xsl:otherwise>'
206                    . '<xsl:choose>';
207          }
208   
209          // Iterate over codes, create an <xsl:when> for each emote
210          foreach ($this->collection as $code => $template)
211          {
212              $xsl .= '<xsl:when test=".=' . htmlspecialchars(XPath::export($code), ENT_COMPAT) . '">'
213                    . $template
214                    . '</xsl:when>';
215          }
216   
217          // Finish it with an <xsl:otherwise> that displays the unknown codes as text
218          $xsl .= '<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>';
219   
220          // Close the emote switch
221          $xsl .= '</xsl:choose>';
222   
223          // Close the "notIf" condition if applicable
224          if (!empty($this->notIfCondition))
225          {
226              $xsl .= '</xsl:otherwise></xsl:choose>';
227          }
228   
229          return $xsl;
230      }
231  }