/src/community/vendor/s9e/text-formatter/src/Plugins/MediaEmbed/Parser.php

https://bitbucket.org/ke2083/transfans.co.uk-website · PHP · 178 lines · 172 code · 1 blank · 5 comment · 26 complexity · 3991c3c946df776592da53063b2c36d8 MD5 · raw file

  1. <?php
  2. /*
  3. * @package s9e\TextFormatter
  4. * @copyright Copyright (c) 2010-2017 The s9e Authors
  5. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  6. */
  7. namespace s9e\TextFormatter\Plugins\MediaEmbed;
  8. use s9e\TextFormatter\Parser as TagStack;
  9. use s9e\TextFormatter\Parser\Tag;
  10. use s9e\TextFormatter\Plugins\ParserBase;
  11. use s9e\TextFormatter\Utils\Http;
  12. class Parser extends ParserBase
  13. {
  14. protected static $client;
  15. public function parse($text, array $matches)
  16. {
  17. foreach ($matches as $m)
  18. {
  19. $url = $m[0][0];
  20. $pos = $m[0][1];
  21. $len = \strlen($url);
  22. $tag = $this->parser->addSelfClosingTag($this->config['tagName'], $pos, $len, -10);
  23. $tag->setAttribute('url', $url);
  24. }
  25. }
  26. public static function filterTag(Tag $tag, TagStack $tagStack, array $sites)
  27. {
  28. if ($tag->hasAttribute('site'))
  29. self::addTagFromMediaId($tag, $tagStack, $sites);
  30. elseif ($tag->hasAttribute('url'))
  31. self::addTagFromMediaUrl($tag, $tagStack, $sites);
  32. return \false;
  33. }
  34. public static function hasNonDefaultAttribute(Tag $tag)
  35. {
  36. foreach ($tag->getAttributes() as $attrName => $void)
  37. if ($attrName !== 'url')
  38. return \true;
  39. return \false;
  40. }
  41. public static function scrape(Tag $tag, array $scrapeConfig, $cacheDir = \null)
  42. {
  43. if ($tag->hasAttribute('url'))
  44. {
  45. $url = $tag->getAttribute('url');
  46. if (\preg_match('#^https?://[^<>"\'\\s]+$#Di', $url))
  47. {
  48. $url = \strtolower(\substr($url, 0, 5)) . \substr($url, 5);
  49. foreach ($scrapeConfig as $scrape)
  50. self::scrapeEntry($url, $tag, $scrape, $cacheDir);
  51. }
  52. }
  53. return \true;
  54. }
  55. protected static function addSiteTag(Tag $tag, TagStack $tagStack, $siteId)
  56. {
  57. $endTag = $tag->getEndTag();
  58. if ($endTag)
  59. {
  60. $startPos = $tag->getPos();
  61. $startLen = $tag->getLen();
  62. $endPos = $endTag->getPos();
  63. $endLen = $endTag->getLen();
  64. }
  65. else
  66. {
  67. $startPos = $tag->getPos();
  68. $startLen = 0;
  69. $endPos = $tag->getPos() + $tag->getLen();
  70. $endLen = 0;
  71. }
  72. $tagStack->addTagPair(\strtoupper($siteId), $startPos, $startLen, $endPos, $endLen, $tag->getSortPriority())->setAttributes($tag->getAttributes());
  73. }
  74. protected static function addTagFromMediaId(Tag $tag, TagStack $tagStack, array $sites)
  75. {
  76. $siteId = \strtolower($tag->getAttribute('site'));
  77. if (\in_array($siteId, $sites, \true))
  78. self::addSiteTag($tag, $tagStack, $siteId);
  79. }
  80. protected static function addTagFromMediaUrl(Tag $tag, TagStack $tagStack, array $sites)
  81. {
  82. $p = \parse_url($tag->getAttribute('url'));
  83. if (isset($p['scheme']) && isset($sites[$p['scheme'] . ':']))
  84. $siteId = $sites[$p['scheme'] . ':'];
  85. elseif (isset($p['host']))
  86. $siteId = self::findSiteIdByHost($p['host'], $sites);
  87. if (!empty($siteId))
  88. self::addSiteTag($tag, $tagStack, $siteId);
  89. }
  90. protected static function findSiteIdByHost($host, array $sites)
  91. {
  92. do
  93. {
  94. if (isset($sites[$host]))
  95. return $sites[$host];
  96. $pos = \strpos($host, '.');
  97. if ($pos === \false)
  98. break;
  99. $host = \substr($host, 1 + $pos);
  100. }
  101. while ($host > '');
  102. return \false;
  103. }
  104. protected static function getHttpClient()
  105. {
  106. if (!isset(self::$client))
  107. self::$client = Http::getClient();
  108. self::$client->timeout = 10;
  109. return self::$client;
  110. }
  111. protected static function replaceTokens($url, array $vars)
  112. {
  113. return \preg_replace_callback(
  114. '#\\{@(\\w+)\\}#',
  115. function ($m) use ($vars)
  116. {
  117. return (isset($vars[$m[1]])) ? $vars[$m[1]] : '';
  118. },
  119. $url
  120. );
  121. }
  122. protected static function scrapeEntry($url, Tag $tag, array $scrape, $cacheDir)
  123. {
  124. list($matchRegexps, $extractRegexps, $attrNames) = $scrape;
  125. if (!self::tagIsMissingAnyAttribute($tag, $attrNames))
  126. return;
  127. $vars = [];
  128. $matched = \false;
  129. foreach ((array) $matchRegexps as $matchRegexp)
  130. if (\preg_match($matchRegexp, $url, $m))
  131. {
  132. $vars += $m;
  133. $matched = \true;
  134. }
  135. if (!$matched)
  136. return;
  137. $vars += $tag->getAttributes();
  138. $scrapeUrl = (isset($scrape[3])) ? self::replaceTokens($scrape[3], $vars) : $url;
  139. self::scrapeUrl($scrapeUrl, $tag, (array) $extractRegexps, $cacheDir);
  140. }
  141. protected static function scrapeUrl($url, Tag $tag, array $regexps, $cacheDir)
  142. {
  143. $content = self::wget($url, $cacheDir);
  144. foreach ($regexps as $regexp)
  145. if (\preg_match($regexp, $content, $m))
  146. foreach ($m as $k => $v)
  147. if (!\is_numeric($k) && !$tag->hasAttribute($k))
  148. $tag->setAttribute($k, $v);
  149. }
  150. protected static function tagIsMissingAnyAttribute(Tag $tag, array $attrNames)
  151. {
  152. foreach ($attrNames as $attrName)
  153. if (!$tag->hasAttribute($attrName))
  154. return \true;
  155. return \false;
  156. }
  157. protected static function wget($url, $cacheDir = \null)
  158. {
  159. $prefix = '';
  160. $url = \preg_replace('(#.*)s', '', $url);
  161. if (isset($cacheDir) && \file_exists($cacheDir))
  162. {
  163. $cacheFile = $cacheDir . '/http.' . \crc32($url);
  164. if (\extension_loaded('zlib'))
  165. {
  166. $prefix = 'compress.zlib://';
  167. $cacheFile .= '.gz';
  168. }
  169. if (\file_exists($cacheFile))
  170. return \file_get_contents($prefix . $cacheFile);
  171. }
  172. $content = @self::getHttpClient()->get($url, ['User-Agent: PHP (not Mozilla)']);
  173. if (isset($cacheFile) && !empty($content))
  174. \file_put_contents($prefix . $cacheFile, $content);
  175. return $content;
  176. }
  177. }