[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Plugins/MediaEmbed/ -> Configurator.php (source)

   1  <?php
   2  
   3  /**
   4  * @package   s9e\TextFormatter
   5  * @copyright Copyright (c) 2010-2022 The s9e authors
   6  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
   7  */
   8  namespace s9e\TextFormatter\Plugins\MediaEmbed;
   9  
  10  use InvalidArgumentException;
  11  use RuntimeException;
  12  use s9e\TextFormatter\Configurator\Helpers\FilterHelper;
  13  use s9e\TextFormatter\Configurator\Items\Regexp;
  14  use s9e\TextFormatter\Configurator\Items\Tag;
  15  use s9e\TextFormatter\Configurator\JavaScript\Dictionary;
  16  use s9e\TextFormatter\Plugins\ConfiguratorBase;
  17  use s9e\TextFormatter\Plugins\MediaEmbed\Configurator\Collections\CachedDefinitionCollection;
  18  use s9e\TextFormatter\Plugins\MediaEmbed\Configurator\TemplateBuilder;
  19  
  20  class Configurator extends ConfiguratorBase
  21  {
  22      /**
  23      * @var array List of filters that are explicitly allowed in attribute definitions
  24      */
  25      public $allowedFilters = ['htmlspecialchars_decode', 'stripslashes', 'urldecode'];
  26  
  27      /**
  28      * @var bool Whether to create the MEDIA BBCode
  29      */
  30      protected $createMediaBBCode = true;
  31  
  32      /**
  33      * @var Configurator\Collections\SiteDefinitionCollection Default sites
  34      */
  35      public $defaultSites;
  36  
  37      /**
  38      * {@inheritdoc}
  39      */
  40      protected $quickMatch = '://';
  41  
  42      /**
  43      * {@inheritdoc}
  44      */
  45      protected $regexp = '/\\bhttps?:\\/\\/[^["\'\\s]+/Si';
  46  
  47      /**
  48      * @var array Configured sites
  49      */
  50      protected $sites = [];
  51  
  52      /**
  53      * @var string Name of the tag used to handle embeddable URLs
  54      */
  55      protected $tagName = 'MEDIA';
  56  
  57      /**
  58      * @var TemplateBuilder
  59      */
  60      protected $templateBuilder;
  61  
  62      /**
  63      * {@inheritdoc}
  64      */
  65  	protected function setUp()
  66      {
  67          $this->defaultSites    = new CachedDefinitionCollection;
  68          $this->templateBuilder = new TemplateBuilder;
  69  
  70          $this->configurator->registeredVars['MediaEmbed.hosts'] = new Dictionary;
  71          $this->configurator->registeredVars['MediaEmbed.sites'] = new Dictionary;
  72  
  73          // Create a MEDIA tag
  74          $this->createMediaTag();
  75  
  76          // Create a [MEDIA] BBCode if applicable
  77          if ($this->createMediaBBCode)
  78          {
  79              $this->configurator->BBCodes->set($this->tagName, ['contentAttributes' => ['url']]);
  80          }
  81      }
  82  
  83      /**
  84      * {@inheritdoc}
  85      */
  86  	public function asConfig()
  87      {
  88          if (empty($this->sites))
  89          {
  90              return;
  91          }
  92  
  93          return [
  94              'quickMatch' => $this->quickMatch,
  95              'regexp'     => $this->regexp,
  96              'tagName'    => $this->tagName
  97          ];
  98      }
  99  
 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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1