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: 7.86 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\MediaEmbed;
009   
010  use InvalidArgumentException;
011  use RuntimeException;
012  use s9e\TextFormatter\Configurator\Helpers\FilterHelper;
013  use s9e\TextFormatter\Configurator\Items\Regexp;
014  use s9e\TextFormatter\Configurator\Items\Tag;
015  use s9e\TextFormatter\Configurator\JavaScript\Dictionary;
016  use s9e\TextFormatter\Plugins\ConfiguratorBase;
017  use s9e\TextFormatter\Plugins\MediaEmbed\Configurator\Collections\CachedDefinitionCollection;
018  use s9e\TextFormatter\Plugins\MediaEmbed\Configurator\TemplateBuilder;
019   
020  class Configurator extends ConfiguratorBase
021  {
022      /**
023      * @var array List of filters that are explicitly allowed in attribute definitions
024      */
025      public $allowedFilters = ['htmlspecialchars_decode', 'stripslashes', 'urldecode'];
026   
027      /**
028      * @var bool Whether to create the MEDIA BBCode
029      */
030      protected $createMediaBBCode = true;
031   
032      /**
033      * @var Configurator\Collections\SiteDefinitionCollection Default sites
034      */
035      public $defaultSites;
036   
037      /**
038      * {@inheritdoc}
039      */
040      protected $quickMatch = '://';
041   
042      /**
043      * {@inheritdoc}
044      */
045      protected $regexp = '/\\bhttps?:\\/\\/[^["\'\\s]+/Si';
046   
047      /**
048      * @var array Configured sites
049      */
050      protected $sites = [];
051   
052      /**
053      * @var string Name of the tag used to handle embeddable URLs
054      */
055      protected $tagName = 'MEDIA';
056   
057      /**
058      * @var TemplateBuilder
059      */
060      protected $templateBuilder;
061   
062      /**
063      * {@inheritdoc}
064      */
065      protected function setUp()
066      {
067          $this->defaultSites    = new CachedDefinitionCollection;
068          $this->templateBuilder = new TemplateBuilder;
069   
070          $this->configurator->registeredVars['MediaEmbed.hosts'] = new Dictionary;
071          $this->configurator->registeredVars['MediaEmbed.sites'] = new Dictionary;
072   
073          // Create a MEDIA tag
074          $this->createMediaTag();
075   
076          // Create a [MEDIA] BBCode if applicable
077          if ($this->createMediaBBCode)
078          {
079              $this->configurator->BBCodes->set($this->tagName, ['contentAttributes' => ['url']]);
080          }
081      }
082   
083      /**
084      * {@inheritdoc}
085      */
086      public function asConfig()
087      {
088          if (empty($this->sites))
089          {
090              return;
091          }
092   
093          return [
094              'quickMatch' => $this->quickMatch,
095              'regexp'     => $this->regexp,
096              'tagName'    => $this->tagName
097          ];
098      }
099   
100      /**
101      * Add a media site
102      *
103      * @param  string $siteId     Site's ID
104      * @param  array  $siteConfig Site's config
105      * @return Tag                Tag created for this site
106      */
107      public function add($siteId, array $siteConfig = null)
108      {
109          // Normalize or retrieve the site definition
110          $siteId = $this->normalizeId($siteId);
111          if (isset($siteConfig))
112          {
113              $siteConfig = $this->defaultSites->normalizeValue($siteConfig);
114          }
115          else
116          {
117              $siteConfig = $this->defaultSites->get($siteId);
118          }
119          $siteConfig['extract'] = $this->convertRegexps($siteConfig['extract']);
120          $siteConfig['scrape']  = $this->convertScrapes($siteConfig['scrape']);
121   
122          // Check the safety of attribute filters
123          $this->checkAttributeFilters($siteConfig['attributes']);
124   
125          // Create the tag for this site
126          $tag = $this->addTag($siteId, $siteConfig);
127   
128          // Update the configurator's data
129          $this->sites[$siteId] = $siteConfig;
130          foreach ($siteConfig['host'] as $host)
131          {
132              $this->configurator->registeredVars['MediaEmbed.hosts'][$host] = $siteId;
133          }
134          $this->configurator->registeredVars['MediaEmbed.sites'][$siteId] = [$siteConfig['extract'], $siteConfig['scrape']];
135   
136          return $tag;
137      }
138   
139      /**
140      * Return the list of configured sites
141      *
142      * @return array Site's ID as keys, site's config as values
143      */
144      public function getSites()
145      {
146          return $this->sites;
147      }
148   
149      /**
150      * Create and return a tag that handles given media site
151      *
152      * @param  string $siteId
153      * @param  array  $siteConfig
154      * @return Tag
155      */
156      protected function addTag($siteId, array $siteConfig)
157      {
158          $tag = new Tag([
159              'attributes' => $this->getAttributesConfig($siteConfig),
160              'rules'      => [
161                  'allowChild' => 'URL',
162                  'autoClose'  => true,
163                  'denyChild'  => [$siteId, $this->tagName]
164              ],
165              'template'   => $this->templateBuilder->build($siteId, $siteConfig)
166          ]);
167   
168          $this->configurator->templateNormalizer->normalizeTag($tag);
169          $this->configurator->templateChecker->checkTag($tag);
170          $this->configurator->tags->add($siteId, $tag);
171   
172          return $tag;
173      }
174   
175      /**
176      * Check the safety of given attributes
177      *
178      * @param  array $attributes
179      * @return void
180      */
181      protected function checkAttributeFilters(array $attributes)
182      {
183          foreach ($attributes as $attrConfig)
184          {
185              if (empty($attrConfig['filterChain']))
186              {
187                  continue;
188              }
189              foreach ($attrConfig['filterChain'] as $filter)
190              {
191                  if (!FilterHelper::isAllowed($filter, $this->allowedFilters))
192                  {
193                      throw new RuntimeException("Filter '$filter' is not allowed in media sites");
194                  }
195              }
196          }
197      }
198   
199      /**
200      * Convert given regexp to a [regexp, map] pair
201      *
202      * @param  string $regexp Original regexp
203      * @return array          [regexp, [list of captures' names]]
204      */
205      protected function convertRegexp($regexp)
206      {
207          $regexp = new Regexp($regexp);
208   
209          return [$regexp, $regexp->getCaptureNames()];
210      }
211   
212      /**
213      * Convert a list of regexps
214      *
215      * @param  string[] $regexps Original list
216      * @return array[]           Converted list
217      */
218      protected function convertRegexps(array $regexps)
219      {
220          return array_map([$this, 'convertRegexp'], $regexps);
221      }
222   
223      /**
224      * Convert all regexps in a scraping config
225      *
226      * @param  array $config Original config
227      * @return array         Converted config
228      */
229      protected function convertScrapeConfig(array $config)
230      {
231          $config['extract'] = $this->convertRegexps($config['extract']);
232          $config['match']   = $this->convertRegexps($config['match']);
233   
234          return $config;
235      }
236   
237      /**
238      * Convert all regexps in a list of scraping configs
239      *
240      * @param  array[] $scrapes Original config
241      * @return array[]          Converted config
242      */
243      protected function convertScrapes(array $scrapes)
244      {
245          return array_map([$this, 'convertScrapeConfig'], $scrapes);
246      }
247   
248      /**
249      * Create the default MEDIA tag
250      *
251      * @return void
252      */
253      protected function createMediaTag()
254      {
255          $tag = $this->configurator->tags->add($this->tagName);
256   
257          // This tag should not need to be closed and should not contain itself
258          $tag->rules->autoClose();
259          $tag->rules->denyChild($this->tagName);
260   
261          // Empty this tag's filter chain and add our tag filter
262          $tag->filterChain->clear();
263          $tag->filterChain
264              ->append(__NAMESPACE__ . '\\Parser::filterTag')
265              ->resetParameters()
266              ->addParameterByName('tag')
267              ->addParameterByName('parser')
268              ->addParameterByName('MediaEmbed.hosts')
269              ->addParameterByName('MediaEmbed.sites')
270              ->addParameterByName('cacheDir')
271              ->setJS(file_get_contents(__DIR__ . '/Parser/tagFilter.js'));
272      }
273   
274      /**
275      * Return the list of named captures from a list of [regexp, map] pairs
276      *
277      * @param  array[] $regexps List of [regexp, map] pairs
278      * @return string[]
279      */
280      protected function getAttributeNamesFromRegexps(array $regexps)
281      {
282          $attrNames = [];
283          foreach ($regexps as list($regexp, $map))
284          {
285              $attrNames += array_flip(array_filter($map));
286          }
287   
288          return $attrNames;
289      }
290   
291      /**
292      * Get the attributes config for given site config
293      *
294      * @param  array $siteConfig Site's config
295      * @return array             Map of [attrName => attrConfig]
296      */
297      protected function getAttributesConfig(array $siteConfig)
298      {
299          $attrNames = $this->getAttributeNamesFromRegexps($siteConfig['extract']);
300          foreach ($siteConfig['scrape'] as $scrapeConfig)
301          {
302              $attrNames += $this->getAttributeNamesFromRegexps($scrapeConfig['extract']);
303          }
304   
305          $attributes = $siteConfig['attributes'] + array_fill_keys(array_keys($attrNames), []);
306          foreach ($attributes as &$attrConfig)
307          {
308              $attrConfig += ['required' => false];
309          }
310          unset($attrConfig);
311   
312          return $attributes;
313      }
314   
315      /**
316      * Validate and normalize a site ID
317      *
318      * @param  string $siteId
319      * @return string
320      */
321      protected function normalizeId($siteId)
322      {
323          $siteId = strtolower($siteId);
324   
325          if (!preg_match('(^[a-z0-9]+$)', $siteId))
326          {
327              throw new InvalidArgumentException('Invalid site ID');
328          }
329   
330          return $siteId;
331      }
332  }