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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Parser.php
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 s9e\TextFormatter\Parser as TagStack;
011 use s9e\TextFormatter\Parser\Tag;
012 use s9e\TextFormatter\Plugins\ParserBase;
013 use s9e\TextFormatter\Utils\Http;
014
015 class Parser extends ParserBase
016 {
017 /**
018 * @var \s9e\TextFormatter\Utils\Http\Client Client used to perform HTTP request
019 */
020 protected static $client;
021
022 /**
023 * @var string|null Cache dir used by cached client
024 */
025 protected static $clientCacheDir;
026
027 /**
028 * {@inheritdoc}
029 */
030 public function parse($text, array $matches)
031 {
032 foreach ($matches as $m)
033 {
034 $tagName = $this->config['tagName'];
035 $url = $m[0][0];
036 $pos = $m[0][1];
037 $len = strlen($url);
038
039 // Give that tag priority over other tags such as Autolink's
040 $this->parser->addSelfClosingTag($tagName, $pos, $len, -10)->setAttribute('url', $url);
041 }
042 }
043
044 /**
045 * Filter a MEDIA tag
046 *
047 * This will always invalidate the original tag, and possibly replace it with the tag that
048 * corresponds to the media site
049 *
050 * @param Tag $tag The original tag
051 * @param TagStack $tagStack Parser instance, so that we can add the new tag to the stack
052 * @param array $hosts Map of [hostname => siteId]
053 * @param array $sites Map of [siteId => siteConfig]
054 * @param string|null $cacheDir Path to the cache directory
055 * @return void
056 */
057 public static function filterTag(Tag $tag, TagStack $tagStack, array $hosts, array $sites, $cacheDir)
058 {
059 // Always invalidate this tag
060 $tag->invalidate();
061
062 if ($tag->hasAttribute('url'))
063 {
064 $url = $tag->getAttribute('url');
065 $siteId = self::getSiteIdFromUrl($url, $hosts);
066 if (isset($sites[$siteId]))
067 {
068 $attributes = self::getAttributes($url, $sites[$siteId], $cacheDir);
069 if (!empty($attributes))
070 {
071 self::createTag(strtoupper($siteId), $tagStack, $tag)->setAttributes($attributes);
072 }
073 }
074 }
075 }
076
077 /**
078 * Add named captures from a set of regular expressions to a set of attributes
079 *
080 * @param array &$attributes Associative array of strings
081 * @param string $string Text to match
082 * @param array[] $regexps List of [regexp, map] pairs
083 * @return bool Whether any regexp matched
084 */
085 protected static function addNamedCaptures(array &$attributes, $string, array $regexps)
086 {
087 $matched = 0;
088 foreach ($regexps as list($regexp, $map))
089 {
090 $matched += preg_match($regexp, $string, $m);
091 foreach ($map as $i => $name)
092 {
093 if (isset($m[$i]) && $m[$i] !== '' && $name !== '')
094 {
095 $attributes[$name] = $m[$i];
096 }
097 }
098 }
099
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 }