[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |