[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Plugins/MediaEmbed/ -> Parser.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 s9e\TextFormatter\Parser as TagStack;
  11  use s9e\TextFormatter\Parser\Tag;
  12  use s9e\TextFormatter\Plugins\ParserBase;
  13  use s9e\TextFormatter\Utils\Http;
  14  
  15  class Parser extends ParserBase
  16  {
  17      /**
  18      * @var \s9e\TextFormatter\Utils\Http\Client Client used to perform HTTP request
  19      */
  20      protected static $client;
  21  
  22      /**
  23      * @var string|null Cache dir used by cached client
  24      */
  25      protected static $clientCacheDir;
  26  
  27      /**
  28      * {@inheritdoc}
  29      */
  30  	public function parse($text, array $matches)
  31      {
  32          foreach ($matches as $m)
  33          {
  34              $tagName = $this->config['tagName'];
  35              $url     = $m[0][0];
  36              $pos     = $m[0][1];
  37              $len     = strlen($url);
  38  
  39              // Give that tag priority over other tags such as Autolink's
  40              $this->parser->addSelfClosingTag($tagName, $pos, $len, -10)->setAttribute('url', $url);
  41          }
  42      }
  43  
  44      /**
  45      * Filter a MEDIA tag
  46      *
  47      * This will always invalidate the original tag, and possibly replace it with the tag that
  48      * corresponds to the media site
  49      *
  50      * @param  Tag         $tag      The original tag
  51      * @param  TagStack    $tagStack Parser instance, so that we can add the new tag to the stack
  52      * @param  array       $hosts    Map of [hostname => siteId]
  53      * @param  array       $sites    Map of [siteId => siteConfig]
  54      * @param  string|null $cacheDir Path to the cache directory
  55      * @return void
  56      */
  57  	public static function filterTag(Tag $tag, TagStack $tagStack, array $hosts, array $sites, $cacheDir)
  58      {
  59          // Always invalidate this tag
  60          $tag->invalidate();
  61  
  62          if ($tag->hasAttribute('url'))
  63          {
  64              $url    = $tag->getAttribute('url');
  65              $siteId = self::getSiteIdFromUrl($url, $hosts);
  66              if (isset($sites[$siteId]))
  67              {
  68                  $attributes = self::getAttributes($url, $sites[$siteId], $cacheDir);
  69                  if (!empty($attributes))
  70                  {
  71                      self::createTag(strtoupper($siteId), $tagStack, $tag)->setAttributes($attributes);
  72                  }
  73              }
  74          }
  75      }
  76  
  77      /**
  78      * Add named captures from a set of regular expressions to a set of attributes
  79      *
  80      * @param  array   &$attributes Associative array of strings
  81      * @param  string   $string     Text to match
  82      * @param  array[]  $regexps    List of [regexp, map] pairs
  83      * @return bool                 Whether any regexp matched
  84      */
  85  	protected static function addNamedCaptures(array &$attributes, $string, array $regexps)
  86      {
  87          $matched = 0;
  88          foreach ($regexps as list($regexp, $map))
  89          {
  90              $matched += preg_match($regexp, $string, $m);
  91              foreach ($map as $i => $name)
  92              {
  93                  if (isset($m[$i]) && $m[$i] !== '' && $name !== '')
  94                  {
  95                      $attributes[$name] = $m[$i];
  96                  }
  97              }
  98          }
  99  
 100          return (bool) $matched;
 101      }
 102  
 103      /**
 104      * Create a tag for a media embed
 105      *
 106      * @param  string   $tagName  Tag's name
 107      * @param  TagStack $tagStack
 108      * @param  Tag      $tag      Reference tag
 109      * @return Tag                New tag
 110      */
 111  	protected static function createTag($tagName, TagStack $tagStack, Tag $tag)
 112      {
 113          $startPos = $tag->getPos();
 114          $endTag   = $tag->getEndTag();
 115          if ($endTag)
 116          {
 117              $startLen = $tag->getLen();
 118              $endPos   = $endTag->getPos();
 119              $endLen   = $endTag->getLen();
 120          }
 121          else
 122          {
 123              $startLen = 0;
 124              $endPos   = $tag->getPos() + $tag->getLen();
 125              $endLen   = 0;
 126          }
 127  
 128          return $tagStack->addTagPair($tagName, $startPos, $startLen, $endPos, $endLen, $tag->getSortPriority());
 129      }
 130  
 131      /**
 132      * Return a set of attributes for given URL based on a site's config
 133      *
 134      * @param  string      $url      Original URL
 135      * @param  array       $config   Site config
 136      * @param  string|null $cacheDir Path to the cache directory
 137      * @return array                 Associative array of attributes
 138      */
 139  	protected static function getAttributes($url, array $config, $cacheDir)
 140      {
 141          $attributes = [];
 142          self::addNamedCaptures($attributes, $url, $config[0]);
 143          foreach ($config[1] as $scrapeConfig)
 144          {
 145              self::scrape($attributes, $url, $scrapeConfig, $cacheDir);
 146          }
 147  
 148          return $attributes;
 149      }
 150  
 151      /**
 152      * Return a cached instance of the HTTP client
 153      *
 154      * @param  string|null $cacheDir
 155      * @return \s9e\TextFormatter\Utils\Http\Client
 156      */
 157  	protected static function getHttpClient($cacheDir)
 158      {
 159          if (!isset(self::$client) || self::$clientCacheDir !== $cacheDir)
 160          {
 161              self::$client = (isset($cacheDir)) ? Http::getCachingClient($cacheDir) : Http::getClient();
 162              self::$clientCacheDir = $cacheDir;
 163          }
 164  
 165          return self::$client;
 166      }
 167  
 168      /**
 169      * Return the siteId that corresponds to given URL
 170      *
 171      * @param  string  $url   Original URL
 172      * @param  array   $hosts Map of [hostname => siteId]
 173      * @return string         URL's siteId, or an empty string
 174      */
 175  	protected static function getSiteIdFromUrl($url, array $hosts)
 176      {
 177          $host = (preg_match('(^https?://([^/]+))', strtolower($url), $m)) ? $m[1] : '';
 178          while ($host > '')
 179          {
 180              if (isset($hosts[$host]))
 181              {
 182                  return $hosts[$host];
 183              }
 184              $host = preg_replace('(^[^.]*.)', '', $host);
 185          }
 186  
 187          return '';
 188      }
 189  
 190      /**
 191      * Interpolate {@vars} in given string
 192      *
 193      * @param  string $str  Original string
 194      * @param  array  $vars Associative array
 195      * @return string       Interpolated string
 196      */
 197  	protected static function interpolateVars($str, array $vars)
 198      {
 199          return preg_replace_callback(
 200              '(\\{@(\\w+)\\})',
 201              function ($m) use ($vars)
 202              {
 203                  return $vars[$m[1]] ?? '';
 204              },
 205              $str
 206          );
 207      }
 208  
 209      /**
 210      * Scrape values and add them to current attributes
 211      *
 212      * @param  array       &$attributes Attributes
 213      * @param  string       $url        Original URL
 214      * @param  array        $config     Scraping config
 215      * @param  string|null  $cacheDir   Path to the cache directory
 216      * @return void
 217      */
 218  	protected static function scrape(array &$attributes, $url, array $config, $cacheDir)
 219      {
 220          $vars = [];
 221          if (self::addNamedCaptures($vars, $url, $config['match']))
 222          {
 223              if (isset($config['url']))
 224              {
 225                  $url = self::interpolateVars($config['url'], $vars + $attributes);
 226              }
 227              if (preg_match('(^https?://[^#]+)i', $url, $m))
 228              {
 229                  $response = self::wget($m[0], $cacheDir, $config);
 230                  self::addNamedCaptures($attributes, $response, $config['extract']);
 231              }
 232          }
 233      }
 234  
 235      /**
 236      * Retrieve external content
 237      *
 238      * @param  string      $url      URL
 239      * @param  string|null $cacheDir Path to the cache directory
 240      * @param  array       $config   Scraping config
 241      * @return string                Response body
 242      */
 243  	protected static function wget($url, $cacheDir, $config)
 244      {
 245          $options = [
 246              'headers'       => (isset($config['header'])) ? (array) $config['header'] : [],
 247              'returnHeaders' => true
 248          ];
 249  
 250          return @self::getHttpClient($cacheDir)->get($url, $options);
 251      }
 252  }


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