diff options
Diffstat (limited to 'inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php')
-rw-r--r-- | inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php new file mode 100644 index 00000000..57e910c2 --- /dev/null +++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php | |||
@@ -0,0 +1,372 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * SimplePie | ||
4 | * | ||
5 | * A PHP-Based RSS and Atom Feed Framework. | ||
6 | * Takes the hard work out of managing a complete RSS/Atom solution. | ||
7 | * | ||
8 | * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without modification, are | ||
12 | * permitted provided that the following conditions are met: | ||
13 | * | ||
14 | * * Redistributions of source code must retain the above copyright notice, this list of | ||
15 | * conditions and the following disclaimer. | ||
16 | * | ||
17 | * * Redistributions in binary form must reproduce the above copyright notice, this list | ||
18 | * of conditions and the following disclaimer in the documentation and/or other materials | ||
19 | * provided with the distribution. | ||
20 | * | ||
21 | * * Neither the name of the SimplePie Team nor the names of its contributors may be used | ||
22 | * to endorse or promote products derived from this software without specific prior | ||
23 | * written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS | ||
26 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
27 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS | ||
28 | * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
33 | * POSSIBILITY OF SUCH DAMAGE. | ||
34 | * | ||
35 | * @package SimplePie | ||
36 | * @version 1.3.1 | ||
37 | * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue | ||
38 | * @author Ryan Parman | ||
39 | * @author Geoffrey Sneddon | ||
40 | * @author Ryan McCue | ||
41 | * @link http://simplepie.org/ SimplePie | ||
42 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License | ||
43 | */ | ||
44 | |||
45 | /** | ||
46 | * Used for feed auto-discovery | ||
47 | * | ||
48 | * | ||
49 | * This class can be overloaded with {@see SimplePie::set_locator_class()} | ||
50 | * | ||
51 | * @package SimplePie | ||
52 | */ | ||
53 | class SimplePie_Locator | ||
54 | { | ||
55 | var $useragent; | ||
56 | var $timeout; | ||
57 | var $file; | ||
58 | var $local = array(); | ||
59 | var $elsewhere = array(); | ||
60 | var $cached_entities = array(); | ||
61 | var $http_base; | ||
62 | var $base; | ||
63 | var $base_location = 0; | ||
64 | var $checked_feeds = 0; | ||
65 | var $max_checked_feeds = 10; | ||
66 | protected $registry; | ||
67 | |||
68 | public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10) | ||
69 | { | ||
70 | $this->file = $file; | ||
71 | $this->useragent = $useragent; | ||
72 | $this->timeout = $timeout; | ||
73 | $this->max_checked_feeds = $max_checked_feeds; | ||
74 | |||
75 | if (class_exists('DOMDocument')) | ||
76 | { | ||
77 | $this->dom = new DOMDocument(); | ||
78 | |||
79 | set_error_handler(array('SimplePie_Misc', 'silence_errors')); | ||
80 | $this->dom->loadHTML($this->file->body); | ||
81 | restore_error_handler(); | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | $this->dom = null; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | public function set_registry(SimplePie_Registry $registry) | ||
90 | { | ||
91 | $this->registry = $registry; | ||
92 | } | ||
93 | |||
94 | public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working) | ||
95 | { | ||
96 | if ($this->is_feed($this->file)) | ||
97 | { | ||
98 | return $this->file; | ||
99 | } | ||
100 | |||
101 | if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) | ||
102 | { | ||
103 | $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file)); | ||
104 | if ($sniffer->get_type() !== 'text/html') | ||
105 | { | ||
106 | return null; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if ($type & ~SIMPLEPIE_LOCATOR_NONE) | ||
111 | { | ||
112 | $this->get_base(); | ||
113 | } | ||
114 | |||
115 | if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) | ||
116 | { | ||
117 | return $working[0]; | ||
118 | } | ||
119 | |||
120 | if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) | ||
121 | { | ||
122 | if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) | ||
123 | { | ||
124 | return $working; | ||
125 | } | ||
126 | |||
127 | if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) | ||
128 | { | ||
129 | return $working; | ||
130 | } | ||
131 | |||
132 | if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) | ||
133 | { | ||
134 | return $working; | ||
135 | } | ||
136 | |||
137 | if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) | ||
138 | { | ||
139 | return $working; | ||
140 | } | ||
141 | } | ||
142 | return null; | ||
143 | } | ||
144 | |||
145 | public function is_feed($file) | ||
146 | { | ||
147 | if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) | ||
148 | { | ||
149 | $sniffer = $this->registry->create('Content_Type_Sniffer', array($file)); | ||
150 | $sniffed = $sniffer->get_type(); | ||
151 | if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) | ||
152 | { | ||
153 | return true; | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | return false; | ||
158 | } | ||
159 | } | ||
160 | elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) | ||
161 | { | ||
162 | return true; | ||
163 | } | ||
164 | else | ||
165 | { | ||
166 | return false; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | public function get_base() | ||
171 | { | ||
172 | if ($this->dom === null) | ||
173 | { | ||
174 | throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); | ||
175 | } | ||
176 | $this->http_base = $this->file->url; | ||
177 | $this->base = $this->http_base; | ||
178 | $elements = $this->dom->getElementsByTagName('base'); | ||
179 | foreach ($elements as $element) | ||
180 | { | ||
181 | if ($element->hasAttribute('href')) | ||
182 | { | ||
183 | $base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base)); | ||
184 | if ($base === false) | ||
185 | { | ||
186 | continue; | ||
187 | } | ||
188 | $this->base = $base; | ||
189 | $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0; | ||
190 | break; | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | public function autodiscovery() | ||
196 | { | ||
197 | $done = array(); | ||
198 | $feeds = array(); | ||
199 | $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds)); | ||
200 | $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds)); | ||
201 | $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds)); | ||
202 | |||
203 | if (!empty($feeds)) | ||
204 | { | ||
205 | return array_values($feeds); | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | return null; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | protected function search_elements_by_tag($name, &$done, $feeds) | ||
214 | { | ||
215 | if ($this->dom === null) | ||
216 | { | ||
217 | throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); | ||
218 | } | ||
219 | |||
220 | $links = $this->dom->getElementsByTagName($name); | ||
221 | foreach ($links as $link) | ||
222 | { | ||
223 | if ($this->checked_feeds === $this->max_checked_feeds) | ||
224 | { | ||
225 | break; | ||
226 | } | ||
227 | if ($link->hasAttribute('href') && $link->hasAttribute('rel')) | ||
228 | { | ||
229 | $rel = array_unique($this->registry->call('Misc', 'space_seperated_tokens', array(strtolower($link->getAttribute('rel'))))); | ||
230 | $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1; | ||
231 | |||
232 | if ($this->base_location < $line) | ||
233 | { | ||
234 | $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); | ||
235 | } | ||
236 | else | ||
237 | { | ||
238 | $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); | ||
239 | } | ||
240 | if ($href === false) | ||
241 | { | ||
242 | continue; | ||
243 | } | ||
244 | |||
245 | if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href])) | ||
246 | { | ||
247 | $this->checked_feeds++; | ||
248 | $headers = array( | ||
249 | 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', | ||
250 | ); | ||
251 | $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent)); | ||
252 | if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) | ||
253 | { | ||
254 | $feeds[$href] = $feed; | ||
255 | } | ||
256 | } | ||
257 | $done[] = $href; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | return $feeds; | ||
262 | } | ||
263 | |||
264 | public function get_links() | ||
265 | { | ||
266 | if ($this->dom === null) | ||
267 | { | ||
268 | throw new SimplePie_Exception('DOMDocument not found, unable to use locator'); | ||
269 | } | ||
270 | |||
271 | $links = $this->dom->getElementsByTagName('a'); | ||
272 | foreach ($links as $link) | ||
273 | { | ||
274 | if ($link->hasAttribute('href')) | ||
275 | { | ||
276 | $href = trim($link->getAttribute('href')); | ||
277 | $parsed = $this->registry->call('Misc', 'parse_url', array($href)); | ||
278 | if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) | ||
279 | { | ||
280 | if ($this->base_location < $link->getLineNo()) | ||
281 | { | ||
282 | $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base)); | ||
287 | } | ||
288 | if ($href === false) | ||
289 | { | ||
290 | continue; | ||
291 | } | ||
292 | |||
293 | $current = $this->registry->call('Misc', 'parse_url', array($this->file->url)); | ||
294 | |||
295 | if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) | ||
296 | { | ||
297 | $this->local[] = $href; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | $this->elsewhere[] = $href; | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | $this->local = array_unique($this->local); | ||
307 | $this->elsewhere = array_unique($this->elsewhere); | ||
308 | if (!empty($this->local) || !empty($this->elsewhere)) | ||
309 | { | ||
310 | return true; | ||
311 | } | ||
312 | return null; | ||
313 | } | ||
314 | |||
315 | public function extension(&$array) | ||
316 | { | ||
317 | foreach ($array as $key => $value) | ||
318 | { | ||
319 | if ($this->checked_feeds === $this->max_checked_feeds) | ||
320 | { | ||
321 | break; | ||
322 | } | ||
323 | if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) | ||
324 | { | ||
325 | $this->checked_feeds++; | ||
326 | |||
327 | $headers = array( | ||
328 | 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', | ||
329 | ); | ||
330 | $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent)); | ||
331 | if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) | ||
332 | { | ||
333 | return $feed; | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | unset($array[$key]); | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | return null; | ||
342 | } | ||
343 | |||
344 | public function body(&$array) | ||
345 | { | ||
346 | foreach ($array as $key => $value) | ||
347 | { | ||
348 | if ($this->checked_feeds === $this->max_checked_feeds) | ||
349 | { | ||
350 | break; | ||
351 | } | ||
352 | if (preg_match('/(rss|rdf|atom|xml)/i', $value)) | ||
353 | { | ||
354 | $this->checked_feeds++; | ||
355 | $headers = array( | ||
356 | 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', | ||
357 | ); | ||
358 | $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent)); | ||
359 | if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) | ||
360 | { | ||
361 | return $feed; | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | unset($array[$key]); | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | return null; | ||
370 | } | ||
371 | } | ||
372 | |||