aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/3rdparty/libraries/simplepie
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas.loeuillet@gmail.com>2013-12-23 02:28:56 -0800
committerNicolas Lœuillet <nicolas.loeuillet@gmail.com>2013-12-23 02:28:56 -0800
commit60fc4f4b1ab37fbfe9021f3fa1395d66a4424ed2 (patch)
tree515c4b9c8286ae363f77722c91acb878151dc386 /inc/3rdparty/libraries/simplepie
parentcbfd5a1019f47fadefd8490dae9f039ae894298d (diff)
parentda5fc42f615eeb45a702604970f94967507fb432 (diff)
downloadwallabag-1.3.0.tar.gz
wallabag-1.3.0.tar.zst
wallabag-1.3.0.zip
Merge pull request #363 from inthepoche/dev1.3.0
poche 1.3.0
Diffstat (limited to 'inc/3rdparty/libraries/simplepie')
-rw-r--r--inc/3rdparty/libraries/simplepie/LICENSE.txt26
-rw-r--r--inc/3rdparty/libraries/simplepie/autoloader.php86
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie.php3058
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Author.php157
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache.php133
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Base.php114
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/DB.php137
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/File.php173
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Memcache.php183
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/MySQL.php438
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Caption.php210
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Category.php157
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php332
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Copyright.php130
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Core.php57
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Credit.php156
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php617
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Enclosure.php1380
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Exception.php52
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/File.php292
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/HTTP/Parser.php500
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/IRI.php1238
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Item.php2964
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Locator.php372
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Misc.php2247
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Net/IPv6.php276
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Parse/Date.php983
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Parser.php407
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Rating.php129
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Registry.php225
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Restriction.php155
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Sanitize.php549
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/Source.php611
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php362
-rw-r--r--inc/3rdparty/libraries/simplepie/library/SimplePie/gzdecode.php371
35 files changed, 19277 insertions, 0 deletions
diff --git a/inc/3rdparty/libraries/simplepie/LICENSE.txt b/inc/3rdparty/libraries/simplepie/LICENSE.txt
new file mode 100644
index 00000000..a822a4bd
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/LICENSE.txt
@@ -0,0 +1,26 @@
1Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon.
2All rights reserved.
3
4Redistribution and use in source and binary forms, with or without modification, are
5permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of
8 conditions and the following disclaimer.
9
10 * Redistributions in binary form must reproduce the above copyright notice, this list
11 of conditions and the following disclaimer in the documentation and/or other materials
12 provided with the distribution.
13
14 * Neither the name of the SimplePie Team nor the names of its contributors may be used
15 to endorse or promote products derived from this software without specific prior
16 written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
19OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
21AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/inc/3rdparty/libraries/simplepie/autoloader.php b/inc/3rdparty/libraries/simplepie/autoloader.php
new file mode 100644
index 00000000..c16a8f8b
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/autoloader.php
@@ -0,0 +1,86 @@
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-2009, 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// autoloader
47spl_autoload_register(array(new SimplePie_Autoloader(), 'autoload'));
48
49if (!class_exists('SimplePie'))
50{
51 trigger_error('Autoloader not registered properly', E_USER_ERROR);
52}
53
54/**
55 * Autoloader class
56 *
57 * @package SimplePie
58 * @subpackage API
59 */
60class SimplePie_Autoloader
61{
62 /**
63 * Constructor
64 */
65 public function __construct()
66 {
67 $this->path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'library';
68 }
69
70 /**
71 * Autoloader
72 *
73 * @param string $class The name of the class to attempt to load.
74 */
75 public function autoload($class)
76 {
77 // Only load the class if it starts with "SimplePie"
78 if (strpos($class, 'SimplePie') !== 0)
79 {
80 return;
81 }
82
83 $filename = $this->path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
84 include $filename;
85 }
86} \ No newline at end of file
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie.php b/inc/3rdparty/libraries/simplepie/library/SimplePie.php
new file mode 100644
index 00000000..b33c635f
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie.php
@@ -0,0 +1,3058 @@
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 * SimplePie Name
47 */
48define('SIMPLEPIE_NAME', 'SimplePie');
49
50/**
51 * SimplePie Version
52 */
53define('SIMPLEPIE_VERSION', '1.3.1');
54
55/**
56 * SimplePie Build
57 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
58 */
59define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build()));
60
61/**
62 * SimplePie Website URL
63 */
64define('SIMPLEPIE_URL', 'http://simplepie.org');
65
66/**
67 * SimplePie Useragent
68 * @see SimplePie::set_useragent()
69 */
70define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
71
72/**
73 * SimplePie Linkback
74 */
75define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
76
77/**
78 * No Autodiscovery
79 * @see SimplePie::set_autodiscovery_level()
80 */
81define('SIMPLEPIE_LOCATOR_NONE', 0);
82
83/**
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
86 */
87define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
88
89/**
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
92 */
93define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
94
95/**
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
98 */
99define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
100
101/**
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
104 */
105define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
106
107/**
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
110 */
111define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
112
113/**
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
116 */
117define('SIMPLEPIE_LOCATOR_ALL', 31);
118
119/**
120 * No known feed type
121 */
122define('SIMPLEPIE_TYPE_NONE', 0);
123
124/**
125 * RSS 0.90
126 */
127define('SIMPLEPIE_TYPE_RSS_090', 1);
128
129/**
130 * RSS 0.91 (Netscape)
131 */
132define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
133
134/**
135 * RSS 0.91 (Userland)
136 */
137define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
138
139/**
140 * RSS 0.91 (both Netscape and Userland)
141 */
142define('SIMPLEPIE_TYPE_RSS_091', 6);
143
144/**
145 * RSS 0.92
146 */
147define('SIMPLEPIE_TYPE_RSS_092', 8);
148
149/**
150 * RSS 0.93
151 */
152define('SIMPLEPIE_TYPE_RSS_093', 16);
153
154/**
155 * RSS 0.94
156 */
157define('SIMPLEPIE_TYPE_RSS_094', 32);
158
159/**
160 * RSS 1.0
161 */
162define('SIMPLEPIE_TYPE_RSS_10', 64);
163
164/**
165 * RSS 2.0
166 */
167define('SIMPLEPIE_TYPE_RSS_20', 128);
168
169/**
170 * RDF-based RSS
171 */
172define('SIMPLEPIE_TYPE_RSS_RDF', 65);
173
174/**
175 * Non-RDF-based RSS (truly intended as syndication format)
176 */
177define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
178
179/**
180 * All RSS
181 */
182define('SIMPLEPIE_TYPE_RSS_ALL', 255);
183
184/**
185 * Atom 0.3
186 */
187define('SIMPLEPIE_TYPE_ATOM_03', 256);
188
189/**
190 * Atom 1.0
191 */
192define('SIMPLEPIE_TYPE_ATOM_10', 512);
193
194/**
195 * All Atom
196 */
197define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
198
199/**
200 * All feed types
201 */
202define('SIMPLEPIE_TYPE_ALL', 1023);
203
204/**
205 * No construct
206 */
207define('SIMPLEPIE_CONSTRUCT_NONE', 0);
208
209/**
210 * Text construct
211 */
212define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
213
214/**
215 * HTML construct
216 */
217define('SIMPLEPIE_CONSTRUCT_HTML', 2);
218
219/**
220 * XHTML construct
221 */
222define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
223
224/**
225 * base64-encoded construct
226 */
227define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
228
229/**
230 * IRI construct
231 */
232define('SIMPLEPIE_CONSTRUCT_IRI', 16);
233
234/**
235 * A construct that might be HTML
236 */
237define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
238
239/**
240 * All constructs
241 */
242define('SIMPLEPIE_CONSTRUCT_ALL', 63);
243
244/**
245 * Don't change case
246 */
247define('SIMPLEPIE_SAME_CASE', 1);
248
249/**
250 * Change to lowercase
251 */
252define('SIMPLEPIE_LOWERCASE', 2);
253
254/**
255 * Change to uppercase
256 */
257define('SIMPLEPIE_UPPERCASE', 4);
258
259/**
260 * PCRE for HTML attributes
261 */
262define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
263
264/**
265 * PCRE for XML attributes
266 */
267define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
268
269/**
270 * XML Namespace
271 */
272define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
273
274/**
275 * Atom 1.0 Namespace
276 */
277define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
278
279/**
280 * Atom 0.3 Namespace
281 */
282define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
283
284/**
285 * RDF Namespace
286 */
287define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
288
289/**
290 * RSS 0.90 Namespace
291 */
292define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
293
294/**
295 * RSS 1.0 Namespace
296 */
297define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
298
299/**
300 * RSS 1.0 Content Module Namespace
301 */
302define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
303
304/**
305 * RSS 2.0 Namespace
306 * (Stupid, I know, but I'm certain it will confuse people less with support.)
307 */
308define('SIMPLEPIE_NAMESPACE_RSS_20', '');
309
310/**
311 * DC 1.0 Namespace
312 */
313define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
314
315/**
316 * DC 1.1 Namespace
317 */
318define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
319
320/**
321 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
322 */
323define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
324
325/**
326 * GeoRSS Namespace
327 */
328define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
329
330/**
331 * Media RSS Namespace
332 */
333define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
334
335/**
336 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
337 */
338define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
339
340/**
341 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
342 */
343define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
344
345/**
346 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
347 */
348define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
349
350/**
351 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
352 */
353define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
354
355/**
356 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
357 */
358define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
359
360/**
361 * iTunes RSS Namespace
362 */
363define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
364
365/**
366 * XHTML Namespace
367 */
368define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
369
370/**
371 * IANA Link Relations Registry
372 */
373define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
374
375/**
376 * No file source
377 */
378define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
379
380/**
381 * Remote file source
382 */
383define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
384
385/**
386 * Local file source
387 */
388define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
389
390/**
391 * fsockopen() file source
392 */
393define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
394
395/**
396 * cURL file source
397 */
398define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
399
400/**
401 * file_get_contents() file source
402 */
403define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
404
405
406
407/**
408 * SimplePie
409 *
410 * @package SimplePie
411 * @subpackage API
412 */
413class SimplePie
414{
415 /**
416 * @var array Raw data
417 * @access private
418 */
419 public $data = array();
420
421 /**
422 * @var mixed Error string
423 * @access private
424 */
425 public $error;
426
427 /**
428 * @var object Instance of SimplePie_Sanitize (or other class)
429 * @see SimplePie::set_sanitize_class()
430 * @access private
431 */
432 public $sanitize;
433
434 /**
435 * @var string SimplePie Useragent
436 * @see SimplePie::set_useragent()
437 * @access private
438 */
439 public $useragent = SIMPLEPIE_USERAGENT;
440
441 /**
442 * @var string Feed URL
443 * @see SimplePie::set_feed_url()
444 * @access private
445 */
446 public $feed_url;
447
448 /**
449 * @var object Instance of SimplePie_File to use as a feed
450 * @see SimplePie::set_file()
451 * @access private
452 */
453 public $file;
454
455 /**
456 * @var string Raw feed data
457 * @see SimplePie::set_raw_data()
458 * @access private
459 */
460 public $raw_data;
461
462 /**
463 * @var int Timeout for fetching remote files
464 * @see SimplePie::set_timeout()
465 * @access private
466 */
467 public $timeout = 10;
468
469 /**
470 * @var bool Forces fsockopen() to be used for remote files instead
471 * of cURL, even if a new enough version is installed
472 * @see SimplePie::force_fsockopen()
473 * @access private
474 */
475 public $force_fsockopen = false;
476
477 /**
478 * @var bool Force the given data/URL to be treated as a feed no matter what
479 * it appears like
480 * @see SimplePie::force_feed()
481 * @access private
482 */
483 public $force_feed = false;
484
485 /**
486 * @var bool Enable/Disable Caching
487 * @see SimplePie::enable_cache()
488 * @access private
489 */
490 public $cache = true;
491
492 /**
493 * @var int Cache duration (in seconds)
494 * @see SimplePie::set_cache_duration()
495 * @access private
496 */
497 public $cache_duration = 3600;
498
499 /**
500 * @var int Auto-discovery cache duration (in seconds)
501 * @see SimplePie::set_autodiscovery_cache_duration()
502 * @access private
503 */
504 public $autodiscovery_cache_duration = 604800; // 7 Days.
505
506 /**
507 * @var string Cache location (relative to executing script)
508 * @see SimplePie::set_cache_location()
509 * @access private
510 */
511 public $cache_location = './cache';
512
513 /**
514 * @var string Function that creates the cache filename
515 * @see SimplePie::set_cache_name_function()
516 * @access private
517 */
518 public $cache_name_function = 'md5';
519
520 /**
521 * @var bool Reorder feed by date descending
522 * @see SimplePie::enable_order_by_date()
523 * @access private
524 */
525 public $order_by_date = true;
526
527 /**
528 * @var mixed Force input encoding to be set to the follow value
529 * (false, or anything type-cast to false, disables this feature)
530 * @see SimplePie::set_input_encoding()
531 * @access private
532 */
533 public $input_encoding = false;
534
535 /**
536 * @var int Feed Autodiscovery Level
537 * @see SimplePie::set_autodiscovery_level()
538 * @access private
539 */
540 public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
541
542 /**
543 * Class registry object
544 *
545 * @var SimplePie_Registry
546 */
547 public $registry;
548
549 /**
550 * @var int Maximum number of feeds to check with autodiscovery
551 * @see SimplePie::set_max_checked_feeds()
552 * @access private
553 */
554 public $max_checked_feeds = 10;
555
556 /**
557 * @var array All the feeds found during the autodiscovery process
558 * @see SimplePie::get_all_discovered_feeds()
559 * @access private
560 */
561 public $all_discovered_feeds = array();
562
563 /**
564 * @var string Web-accessible path to the handler_image.php file.
565 * @see SimplePie::set_image_handler()
566 * @access private
567 */
568 public $image_handler = '';
569
570 /**
571 * @var array Stores the URLs when multiple feeds are being initialized.
572 * @see SimplePie::set_feed_url()
573 * @access private
574 */
575 public $multifeed_url = array();
576
577 /**
578 * @var array Stores SimplePie objects when multiple feeds initialized.
579 * @access private
580 */
581 public $multifeed_objects = array();
582
583 /**
584 * @var array Stores the get_object_vars() array for use with multifeeds.
585 * @see SimplePie::set_feed_url()
586 * @access private
587 */
588 public $config_settings = null;
589
590 /**
591 * @var integer Stores the number of items to return per-feed with multifeeds.
592 * @see SimplePie::set_item_limit()
593 * @access private
594 */
595 public $item_limit = 0;
596
597 /**
598 * @var array Stores the default attributes to be stripped by strip_attributes().
599 * @see SimplePie::strip_attributes()
600 * @access private
601 */
602 public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
603
604 /**
605 * @var array Stores the default tags to be stripped by strip_htmltags().
606 * @see SimplePie::strip_htmltags()
607 * @access private
608 */
609 public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
610
611 /**
612 * The SimplePie class contains feed level data and options
613 *
614 * To use SimplePie, create the SimplePie object with no parameters. You can
615 * then set configuration options using the provided methods. After setting
616 * them, you must initialise the feed using $feed->init(). At that point the
617 * object's methods and properties will be available to you.
618 *
619 * Previously, it was possible to pass in the feed URL along with cache
620 * options directly into the constructor. This has been removed as of 1.3 as
621 * it caused a lot of confusion.
622 *
623 * @since 1.0 Preview Release
624 */
625 public function __construct()
626 {
627 if (version_compare(PHP_VERSION, '5.2', '<'))
628 {
629 trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
630 die();
631 }
632
633 // Other objects, instances created here so we can set options on them
634 $this->sanitize = new SimplePie_Sanitize();
635 $this->registry = new SimplePie_Registry();
636
637 if (func_num_args() > 0)
638 {
639 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
640 trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.', $level);
641
642 $args = func_get_args();
643 switch (count($args)) {
644 case 3:
645 $this->set_cache_duration($args[2]);
646 case 2:
647 $this->set_cache_location($args[1]);
648 case 1:
649 $this->set_feed_url($args[0]);
650 $this->init();
651 }
652 }
653 }
654
655 /**
656 * Used for converting object to a string
657 */
658 public function __toString()
659 {
660 return md5(serialize($this->data));
661 }
662
663 /**
664 * Remove items that link back to this before destroying this object
665 */
666 public function __destruct()
667 {
668 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
669 {
670 if (!empty($this->data['items']))
671 {
672 foreach ($this->data['items'] as $item)
673 {
674 $item->__destruct();
675 }
676 unset($item, $this->data['items']);
677 }
678 if (!empty($this->data['ordered_items']))
679 {
680 foreach ($this->data['ordered_items'] as $item)
681 {
682 $item->__destruct();
683 }
684 unset($item, $this->data['ordered_items']);
685 }
686 }
687 }
688
689 /**
690 * Force the given data/URL to be treated as a feed
691 *
692 * This tells SimplePie to ignore the content-type provided by the server.
693 * Be careful when using this option, as it will also disable autodiscovery.
694 *
695 * @since 1.1
696 * @param bool $enable Force the given data/URL to be treated as a feed
697 */
698 public function force_feed($enable = false)
699 {
700 $this->force_feed = (bool) $enable;
701 }
702
703 /**
704 * Set the URL of the feed you want to parse
705 *
706 * This allows you to enter the URL of the feed you want to parse, or the
707 * website you want to try to use auto-discovery on. This takes priority
708 * over any set raw data.
709 *
710 * You can set multiple feeds to mash together by passing an array instead
711 * of a string for the $url. Remember that with each additional feed comes
712 * additional processing and resources.
713 *
714 * @since 1.0 Preview Release
715 * @see set_raw_data()
716 * @param string|array $url This is the URL (or array of URLs) that you want to parse.
717 */
718 public function set_feed_url($url)
719 {
720 $this->multifeed_url = array();
721 if (is_array($url))
722 {
723 foreach ($url as $value)
724 {
725 $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
726 }
727 }
728 else
729 {
730 $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
731 }
732 }
733
734 /**
735 * Set an instance of {@see SimplePie_File} to use as a feed
736 *
737 * @param SimplePie_File &$file
738 * @return bool True on success, false on failure
739 */
740 public function set_file(&$file)
741 {
742 if ($file instanceof SimplePie_File)
743 {
744 $this->feed_url = $file->url;
745 $this->file =& $file;
746 return true;
747 }
748 return false;
749 }
750
751 /**
752 * Set the raw XML data to parse
753 *
754 * Allows you to use a string of RSS/Atom data instead of a remote feed.
755 *
756 * If you have a feed available as a string in PHP, you can tell SimplePie
757 * to parse that data string instead of a remote feed. Any set feed URL
758 * takes precedence.
759 *
760 * @since 1.0 Beta 3
761 * @param string $data RSS or Atom data as a string.
762 * @see set_feed_url()
763 */
764 public function set_raw_data($data)
765 {
766 $this->raw_data = $data;
767 }
768
769 /**
770 * Set the the default timeout for fetching remote feeds
771 *
772 * This allows you to change the maximum time the feed's server to respond
773 * and send the feed back.
774 *
775 * @since 1.0 Beta 3
776 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
777 */
778 public function set_timeout($timeout = 10)
779 {
780 $this->timeout = (int) $timeout;
781 }
782
783 /**
784 * Force SimplePie to use fsockopen() instead of cURL
785 *
786 * @since 1.0 Beta 3
787 * @param bool $enable Force fsockopen() to be used
788 */
789 public function force_fsockopen($enable = false)
790 {
791 $this->force_fsockopen = (bool) $enable;
792 }
793
794 /**
795 * Enable/disable caching in SimplePie.
796 *
797 * This option allows you to disable caching all-together in SimplePie.
798 * However, disabling the cache can lead to longer load times.
799 *
800 * @since 1.0 Preview Release
801 * @param bool $enable Enable caching
802 */
803 public function enable_cache($enable = true)
804 {
805 $this->cache = (bool) $enable;
806 }
807
808 /**
809 * Set the length of time (in seconds) that the contents of a feed will be
810 * cached
811 *
812 * @param int $seconds The feed content cache duration
813 */
814 public function set_cache_duration($seconds = 3600)
815 {
816 $this->cache_duration = (int) $seconds;
817 }
818
819 /**
820 * Set the length of time (in seconds) that the autodiscovered feed URL will
821 * be cached
822 *
823 * @param int $seconds The autodiscovered feed URL cache duration.
824 */
825 public function set_autodiscovery_cache_duration($seconds = 604800)
826 {
827 $this->autodiscovery_cache_duration = (int) $seconds;
828 }
829
830 /**
831 * Set the file system location where the cached files should be stored
832 *
833 * @param string $location The file system location.
834 */
835 public function set_cache_location($location = './cache')
836 {
837 $this->cache_location = (string) $location;
838 }
839
840 /**
841 * Set whether feed items should be sorted into reverse chronological order
842 *
843 * @param bool $enable Sort as reverse chronological order.
844 */
845 public function enable_order_by_date($enable = true)
846 {
847 $this->order_by_date = (bool) $enable;
848 }
849
850 /**
851 * Set the character encoding used to parse the feed
852 *
853 * This overrides the encoding reported by the feed, however it will fall
854 * back to the normal encoding detection if the override fails
855 *
856 * @param string $encoding Character encoding
857 */
858 public function set_input_encoding($encoding = false)
859 {
860 if ($encoding)
861 {
862 $this->input_encoding = (string) $encoding;
863 }
864 else
865 {
866 $this->input_encoding = false;
867 }
868 }
869
870 /**
871 * Set how much feed autodiscovery to do
872 *
873 * @see SIMPLEPIE_LOCATOR_NONE
874 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
875 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
876 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
877 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
878 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
879 * @see SIMPLEPIE_LOCATOR_ALL
880 * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
881 */
882 public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
883 {
884 $this->autodiscovery = (int) $level;
885 }
886
887 /**
888 * Get the class registry
889 *
890 * Use this to override SimplePie's default classes
891 * @see SimplePie_Registry
892 * @return SimplePie_Registry
893 */
894 public function &get_registry()
895 {
896 return $this->registry;
897 }
898
899 /**#@+
900 * Useful when you are overloading or extending SimplePie's default classes.
901 *
902 * @deprecated Use {@see get_registry()} instead
903 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
904 * @param string $class Name of custom class
905 * @return boolean True on success, false otherwise
906 */
907 /**
908 * Set which class SimplePie uses for caching
909 */
910 public function set_cache_class($class = 'SimplePie_Cache')
911 {
912 return $this->registry->register('Cache', $class, true);
913 }
914
915 /**
916 * Set which class SimplePie uses for auto-discovery
917 */
918 public function set_locator_class($class = 'SimplePie_Locator')
919 {
920 return $this->registry->register('Locator', $class, true);
921 }
922
923 /**
924 * Set which class SimplePie uses for XML parsing
925 */
926 public function set_parser_class($class = 'SimplePie_Parser')
927 {
928 return $this->registry->register('Parser', $class, true);
929 }
930
931 /**
932 * Set which class SimplePie uses for remote file fetching
933 */
934 public function set_file_class($class = 'SimplePie_File')
935 {
936 return $this->registry->register('File', $class, true);
937 }
938
939 /**
940 * Set which class SimplePie uses for data sanitization
941 */
942 public function set_sanitize_class($class = 'SimplePie_Sanitize')
943 {
944 return $this->registry->register('Sanitize', $class, true);
945 }
946
947 /**
948 * Set which class SimplePie uses for handling feed items
949 */
950 public function set_item_class($class = 'SimplePie_Item')
951 {
952 return $this->registry->register('Item', $class, true);
953 }
954
955 /**
956 * Set which class SimplePie uses for handling author data
957 */
958 public function set_author_class($class = 'SimplePie_Author')
959 {
960 return $this->registry->register('Author', $class, true);
961 }
962
963 /**
964 * Set which class SimplePie uses for handling category data
965 */
966 public function set_category_class($class = 'SimplePie_Category')
967 {
968 return $this->registry->register('Category', $class, true);
969 }
970
971 /**
972 * Set which class SimplePie uses for feed enclosures
973 */
974 public function set_enclosure_class($class = 'SimplePie_Enclosure')
975 {
976 return $this->registry->register('Enclosure', $class, true);
977 }
978
979 /**
980 * Set which class SimplePie uses for `<media:text>` captions
981 */
982 public function set_caption_class($class = 'SimplePie_Caption')
983 {
984 return $this->registry->register('Caption', $class, true);
985 }
986
987 /**
988 * Set which class SimplePie uses for `<media:copyright>`
989 */
990 public function set_copyright_class($class = 'SimplePie_Copyright')
991 {
992 return $this->registry->register('Copyright', $class, true);
993 }
994
995 /**
996 * Set which class SimplePie uses for `<media:credit>`
997 */
998 public function set_credit_class($class = 'SimplePie_Credit')
999 {
1000 return $this->registry->register('Credit', $class, true);
1001 }
1002
1003 /**
1004 * Set which class SimplePie uses for `<media:rating>`
1005 */
1006 public function set_rating_class($class = 'SimplePie_Rating')
1007 {
1008 return $this->registry->register('Rating', $class, true);
1009 }
1010
1011 /**
1012 * Set which class SimplePie uses for `<media:restriction>`
1013 */
1014 public function set_restriction_class($class = 'SimplePie_Restriction')
1015 {
1016 return $this->registry->register('Restriction', $class, true);
1017 }
1018
1019 /**
1020 * Set which class SimplePie uses for content-type sniffing
1021 */
1022 public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1023 {
1024 return $this->registry->register('Content_Type_Sniffer', $class, true);
1025 }
1026
1027 /**
1028 * Set which class SimplePie uses item sources
1029 */
1030 public function set_source_class($class = 'SimplePie_Source')
1031 {
1032 return $this->registry->register('Source', $class, true);
1033 }
1034 /**#@-*/
1035
1036 /**
1037 * Set the user agent string
1038 *
1039 * @param string $ua New user agent string.
1040 */
1041 public function set_useragent($ua = SIMPLEPIE_USERAGENT)
1042 {
1043 $this->useragent = (string) $ua;
1044 }
1045
1046 /**
1047 * Set callback function to create cache filename with
1048 *
1049 * @param mixed $function Callback function
1050 */
1051 public function set_cache_name_function($function = 'md5')
1052 {
1053 if (is_callable($function))
1054 {
1055 $this->cache_name_function = $function;
1056 }
1057 }
1058
1059 /**
1060 * Set options to make SP as fast as possible
1061 *
1062 * Forgoes a substantial amount of data sanitization in favor of speed. This
1063 * turns SimplePie into a dumb parser of feeds.
1064 *
1065 * @param bool $set Whether to set them or not
1066 */
1067 public function set_stupidly_fast($set = false)
1068 {
1069 if ($set)
1070 {
1071 $this->enable_order_by_date(false);
1072 $this->remove_div(false);
1073 $this->strip_comments(false);
1074 $this->strip_htmltags(false);
1075 $this->strip_attributes(false);
1076 $this->set_image_handler(false);
1077 }
1078 }
1079
1080 /**
1081 * Set maximum number of feeds to check with autodiscovery
1082 *
1083 * @param int $max Maximum number of feeds to check
1084 */
1085 public function set_max_checked_feeds($max = 10)
1086 {
1087 $this->max_checked_feeds = (int) $max;
1088 }
1089
1090 public function remove_div($enable = true)
1091 {
1092 $this->sanitize->remove_div($enable);
1093 }
1094
1095 public function strip_htmltags($tags = '', $encode = null)
1096 {
1097 if ($tags === '')
1098 {
1099 $tags = $this->strip_htmltags;
1100 }
1101 $this->sanitize->strip_htmltags($tags);
1102 if ($encode !== null)
1103 {
1104 $this->sanitize->encode_instead_of_strip($tags);
1105 }
1106 }
1107
1108 public function encode_instead_of_strip($enable = true)
1109 {
1110 $this->sanitize->encode_instead_of_strip($enable);
1111 }
1112
1113 public function strip_attributes($attribs = '')
1114 {
1115 if ($attribs === '')
1116 {
1117 $attribs = $this->strip_attributes;
1118 }
1119 $this->sanitize->strip_attributes($attribs);
1120 }
1121
1122 /**
1123 * Set the output encoding
1124 *
1125 * Allows you to override SimplePie's output to match that of your webpage.
1126 * This is useful for times when your webpages are not being served as
1127 * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
1128 * is similar to {@see set_input_encoding()}.
1129 *
1130 * It should be noted, however, that not all character encodings can support
1131 * all characters. If your page is being served as ISO-8859-1 and you try
1132 * to display a Japanese feed, you'll likely see garbled characters.
1133 * Because of this, it is highly recommended to ensure that your webpages
1134 * are served as UTF-8.
1135 *
1136 * The number of supported character encodings depends on whether your web
1137 * host supports {@link http://php.net/mbstring mbstring},
1138 * {@link http://php.net/iconv iconv}, or both. See
1139 * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
1140 * more information.
1141 *
1142 * @param string $encoding
1143 */
1144 public function set_output_encoding($encoding = 'UTF-8')
1145 {
1146 $this->sanitize->set_output_encoding($encoding);
1147 }
1148
1149 public function strip_comments($strip = false)
1150 {
1151 $this->sanitize->strip_comments($strip);
1152 }
1153
1154 /**
1155 * Set element/attribute key/value pairs of HTML attributes
1156 * containing URLs that need to be resolved relative to the feed
1157 *
1158 * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
1159 * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
1160 * |q|@cite
1161 *
1162 * @since 1.0
1163 * @param array|null $element_attribute Element/attribute key/value pairs, null for default
1164 */
1165 public function set_url_replacements($element_attribute = null)
1166 {
1167 $this->sanitize->set_url_replacements($element_attribute);
1168 }
1169
1170 /**
1171 * Set the handler to enable the display of cached images.
1172 *
1173 * @param str $page Web-accessible path to the handler_image.php file.
1174 * @param str $qs The query string that the value should be passed to.
1175 */
1176 public function set_image_handler($page = false, $qs = 'i')
1177 {
1178 if ($page !== false)
1179 {
1180 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1181 }
1182 else
1183 {
1184 $this->image_handler = '';
1185 }
1186 }
1187
1188 /**
1189 * Set the limit for items returned per-feed with multifeeds
1190 *
1191 * @param integer $limit The maximum number of items to return.
1192 */
1193 public function set_item_limit($limit = 0)
1194 {
1195 $this->item_limit = (int) $limit;
1196 }
1197
1198 /**
1199 * Initialize the feed object
1200 *
1201 * This is what makes everything happen. Period. This is where all of the
1202 * configuration options get processed, feeds are fetched, cached, and
1203 * parsed, and all of that other good stuff.
1204 *
1205 * @return boolean True if successful, false otherwise
1206 */
1207 public function init()
1208 {
1209 // Check absolute bare minimum requirements.
1210 if (!extension_loaded('xml') || !extension_loaded('pcre'))
1211 {
1212 return false;
1213 }
1214 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1215 elseif (!extension_loaded('xmlreader'))
1216 {
1217 static $xml_is_sane = null;
1218 if ($xml_is_sane === null)
1219 {
1220 $parser_check = xml_parser_create();
1221 xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1222 xml_parser_free($parser_check);
1223 $xml_is_sane = isset($values[0]['value']);
1224 }
1225 if (!$xml_is_sane)
1226 {
1227 return false;
1228 }
1229 }
1230
1231 if (method_exists($this->sanitize, 'set_registry'))
1232 {
1233 $this->sanitize->set_registry($this->registry);
1234 }
1235
1236 // Pass whatever was set with config options over to the sanitizer.
1237 // Pass the classes in for legacy support; new classes should use the registry instead
1238 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
1239 $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
1240
1241 if (!empty($this->multifeed_url))
1242 {
1243 $i = 0;
1244 $success = 0;
1245 $this->multifeed_objects = array();
1246 $this->error = array();
1247 foreach ($this->multifeed_url as $url)
1248 {
1249 $this->multifeed_objects[$i] = clone $this;
1250 $this->multifeed_objects[$i]->set_feed_url($url);
1251 $single_success = $this->multifeed_objects[$i]->init();
1252 $success |= $single_success;
1253 if (!$single_success)
1254 {
1255 $this->error[$i] = $this->multifeed_objects[$i]->error();
1256 }
1257 $i++;
1258 }
1259 return (bool) $success;
1260 }
1261 elseif ($this->feed_url === null && $this->raw_data === null)
1262 {
1263 return false;
1264 }
1265
1266 $this->error = null;
1267 $this->data = array();
1268 $this->multifeed_objects = array();
1269 $cache = false;
1270
1271 if ($this->feed_url !== null)
1272 {
1273 $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
1274
1275 // Decide whether to enable caching
1276 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1277 {
1278 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
1279 }
1280
1281 // Fetch the data via SimplePie_File into $this->raw_data
1282 if (($fetched = $this->fetch_data($cache)) === true)
1283 {
1284 return true;
1285 }
1286 elseif ($fetched === false) {
1287 return false;
1288 }
1289
1290 list($headers, $sniffed) = $fetched;
1291 }
1292
1293 // Set up array of possible encodings
1294 $encodings = array();
1295
1296 // First check to see if input has been overridden.
1297 if ($this->input_encoding !== false)
1298 {
1299 $encodings[] = $this->input_encoding;
1300 }
1301
1302 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1303 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1304
1305 // RFC 3023 (only applies to sniffed content)
1306 if (isset($sniffed))
1307 {
1308 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1309 {
1310 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1311 {
1312 $encodings[] = strtoupper($charset[1]);
1313 }
1314 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1315 $encodings[] = 'UTF-8';
1316 }
1317 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1318 {
1319 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1320 {
1321 $encodings[] = $charset[1];
1322 }
1323 $encodings[] = 'US-ASCII';
1324 }
1325 // Text MIME-type default
1326 elseif (substr($sniffed, 0, 5) === 'text/')
1327 {
1328 $encodings[] = 'US-ASCII';
1329 }
1330 }
1331
1332 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1333 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1334 $encodings[] = 'UTF-8';
1335 $encodings[] = 'ISO-8859-1';
1336
1337 // There's no point in trying an encoding twice
1338 $encodings = array_unique($encodings);
1339
1340 // Loop through each possible encoding, till we return something, or run out of possibilities
1341 foreach ($encodings as $encoding)
1342 {
1343 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1344 if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
1345 {
1346 // Create new parser
1347 $parser = $this->registry->create('Parser');
1348
1349 // If it's parsed fine
1350 if ($parser->parse($utf8_data, 'UTF-8'))
1351 {
1352 $this->data = $parser->get_data();
1353 if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
1354 {
1355 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1356 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1357 return false;
1358 }
1359
1360 if (isset($headers))
1361 {
1362 $this->data['headers'] = $headers;
1363 }
1364 $this->data['build'] = SIMPLEPIE_BUILD;
1365
1366 // Cache the file if caching is enabled
1367 if ($cache && !$cache->save($this))
1368 {
1369 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1370 }
1371 return true;
1372 }
1373 }
1374 }
1375
1376 if (isset($parser))
1377 {
1378 // We have an error, just set SimplePie_Misc::error to it and quit
1379 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1380 }
1381 else
1382 {
1383 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
1384 }
1385
1386 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1387
1388 return false;
1389 }
1390
1391 /**
1392 * Fetch the data via SimplePie_File
1393 *
1394 * If the data is already cached, attempt to fetch it from there instead
1395 * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache
1396 * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
1397 */
1398 protected function fetch_data(&$cache)
1399 {
1400 // If it's enabled, use the cache
1401 if ($cache)
1402 {
1403 // Load the Cache
1404 $this->data = $cache->load();
1405 if (!empty($this->data))
1406 {
1407 // If the cache is for an outdated build of SimplePie
1408 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1409 {
1410 $cache->unlink();
1411 $this->data = array();
1412 }
1413 // If we've hit a collision just rerun it with caching disabled
1414 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1415 {
1416 $cache = false;
1417 $this->data = array();
1418 }
1419 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1420 elseif (isset($this->data['feed_url']))
1421 {
1422 // If the autodiscovery cache is still valid use it.
1423 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1424 {
1425 // Do not need to do feed autodiscovery yet.
1426 if ($this->data['feed_url'] !== $this->data['url'])
1427 {
1428 $this->set_feed_url($this->data['feed_url']);
1429 return $this->init();
1430 }
1431
1432 $cache->unlink();
1433 $this->data = array();
1434 }
1435 }
1436 // Check if the cache has been updated
1437 elseif ($cache->mtime() + $this->cache_duration < time())
1438 {
1439 // If we have last-modified and/or etag set
1440 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1441 {
1442 $headers = array(
1443 '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',
1444 );
1445 if (isset($this->data['headers']['last-modified']))
1446 {
1447 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1448 }
1449 if (isset($this->data['headers']['etag']))
1450 {
1451 $headers['if-none-match'] = $this->data['headers']['etag'];
1452 }
1453
1454 $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
1455
1456 if ($file->success)
1457 {
1458 if ($file->status_code === 304)
1459 {
1460 $cache->touch();
1461 return true;
1462 }
1463 }
1464 else
1465 {
1466 unset($file);
1467 }
1468 }
1469 }
1470 // If the cache is still valid, just return true
1471 else
1472 {
1473 $this->raw_data = false;
1474 return true;
1475 }
1476 }
1477 // If the cache is empty, delete it
1478 else
1479 {
1480 $cache->unlink();
1481 $this->data = array();
1482 }
1483 }
1484 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1485 if (!isset($file))
1486 {
1487 if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
1488 {
1489 $file =& $this->file;
1490 }
1491 else
1492 {
1493 $headers = array(
1494 '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',
1495 );
1496 $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
1497 }
1498 }
1499 // If the file connection has an error, set SimplePie::error to that and quit
1500 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1501 {
1502 $this->error = $file->error;
1503 return !empty($this->data);
1504 }
1505
1506 if (!$this->force_feed)
1507 {
1508 // Check if the supplied URL is a feed, if it isn't, look for it.
1509 $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
1510
1511 if (!$locate->is_feed($file))
1512 {
1513 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1514 unset($file);
1515 try
1516 {
1517 if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
1518 {
1519 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
1520 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1521 return false;
1522 }
1523 }
1524 catch (SimplePie_Exception $e)
1525 {
1526 // This is usually because DOMDocument doesn't exist
1527 $this->error = $e->getMessage();
1528 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
1529 return false;
1530 }
1531 if ($cache)
1532 {
1533 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1534 if (!$cache->save($this))
1535 {
1536 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1537 }
1538 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
1539 }
1540 $this->feed_url = $file->url;
1541 }
1542 $locate = null;
1543 }
1544
1545 $this->raw_data = $file->body;
1546
1547 $headers = $file->headers;
1548 $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
1549 $sniffed = $sniffer->get_type();
1550
1551 return array($headers, $sniffed);
1552 }
1553
1554 /**
1555 * Get the error message for the occured error
1556 *
1557 * @return string|array Error message, or array of messages for multifeeds
1558 */
1559 public function error()
1560 {
1561 return $this->error;
1562 }
1563
1564 /**
1565 * Get the raw XML
1566 *
1567 * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
1568 * the data instead of printing it.
1569 *
1570 * @return string|boolean Raw XML data, false if the cache is used
1571 */
1572 public function get_raw_data()
1573 {
1574 return $this->raw_data;
1575 }
1576
1577 /**
1578 * Get the character encoding used for output
1579 *
1580 * @since Preview Release
1581 * @return string
1582 */
1583 public function get_encoding()
1584 {
1585 return $this->sanitize->output_encoding;
1586 }
1587
1588 /**
1589 * Send the content-type header with correct encoding
1590 *
1591 * This method ensures that the SimplePie-enabled page is being served with
1592 * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
1593 * and character encoding HTTP headers (character encoding determined by the
1594 * {@see set_output_encoding} config option).
1595 *
1596 * This won't work properly if any content or whitespace has already been
1597 * sent to the browser, because it relies on PHP's
1598 * {@link http://php.net/header header()} function, and these are the
1599 * circumstances under which the function works.
1600 *
1601 * Because it's setting these settings for the entire page (as is the nature
1602 * of HTTP headers), this should only be used once per page (again, at the
1603 * top).
1604 *
1605 * @param string $mime MIME type to serve the page as
1606 */
1607 public function handle_content_type($mime = 'text/html')
1608 {
1609 if (!headers_sent())
1610 {
1611 $header = "Content-type: $mime;";
1612 if ($this->get_encoding())
1613 {
1614 $header .= ' charset=' . $this->get_encoding();
1615 }
1616 else
1617 {
1618 $header .= ' charset=UTF-8';
1619 }
1620 header($header);
1621 }
1622 }
1623
1624 /**
1625 * Get the type of the feed
1626 *
1627 * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against
1628 * using {@link http://php.net/language.operators.bitwise bitwise operators}
1629 *
1630 * @since 0.8 (usage changed to using constants in 1.0)
1631 * @see SIMPLEPIE_TYPE_NONE Unknown.
1632 * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90.
1633 * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
1634 * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
1635 * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91.
1636 * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92.
1637 * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93.
1638 * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94.
1639 * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0.
1640 * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x.
1641 * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS.
1642 * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
1643 * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS.
1644 * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3.
1645 * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0.
1646 * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom.
1647 * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type.
1648 * @return int SIMPLEPIE_TYPE_* constant
1649 */
1650 public function get_type()
1651 {
1652 if (!isset($this->data['type']))
1653 {
1654 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1655 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1656 {
1657 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1658 }
1659 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1660 {
1661 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1662 }
1663 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1664 {
1665 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1666 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1667 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1668 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1669 {
1670 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1671 }
1672 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1673 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1674 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1675 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1676 {
1677 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1678 }
1679 }
1680 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1681 {
1682 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1683 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1684 {
1685 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1686 {
1687 case '0.91':
1688 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1689 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1690 {
1691 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1692 {
1693 case '0':
1694 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1695 break;
1696
1697 case '24':
1698 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1699 break;
1700 }
1701 }
1702 break;
1703
1704 case '0.92':
1705 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1706 break;
1707
1708 case '0.93':
1709 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1710 break;
1711
1712 case '0.94':
1713 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1714 break;
1715
1716 case '2.0':
1717 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1718 break;
1719 }
1720 }
1721 }
1722 else
1723 {
1724 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1725 }
1726 }
1727 return $this->data['type'];
1728 }
1729
1730 /**
1731 * Get the URL for the feed
1732 *
1733 * May or may not be different from the URL passed to {@see set_feed_url()},
1734 * depending on whether auto-discovery was used.
1735 *
1736 * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
1737 * @todo If we have a perm redirect we should return the new URL
1738 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1739 * @todo Also, |atom:link|@rel=self
1740 * @return string|null
1741 */
1742 public function subscribe_url()
1743 {
1744 if ($this->feed_url !== null)
1745 {
1746 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1747 }
1748 else
1749 {
1750 return null;
1751 }
1752 }
1753
1754 /**
1755 * Get data for an feed-level element
1756 *
1757 * This method allows you to get access to ANY element/attribute that is a
1758 * sub-element of the opening feed tag.
1759 *
1760 * The return value is an indexed array of elements matching the given
1761 * namespace and tag name. Each element has `attribs`, `data` and `child`
1762 * subkeys. For `attribs` and `child`, these contain namespace subkeys.
1763 * `attribs` then has one level of associative name => value data (where
1764 * `value` is a string) after the namespace. `child` has tag-indexed keys
1765 * after the namespace, each member of which is an indexed array matching
1766 * this same format.
1767 *
1768 * For example:
1769 * <pre>
1770 * // This is probably a bad example because we already support
1771 * // <media:content> natively, but it shows you how to parse through
1772 * // the nodes.
1773 * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
1774 * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
1775 * $file = $content[0]['attribs']['']['url'];
1776 * echo $file;
1777 * </pre>
1778 *
1779 * @since 1.0
1780 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1781 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1782 * @param string $tag Tag name
1783 * @return array
1784 */
1785 public function get_feed_tags($namespace, $tag)
1786 {
1787 $type = $this->get_type();
1788 if ($type & SIMPLEPIE_TYPE_ATOM_10)
1789 {
1790 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
1791 {
1792 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
1793 }
1794 }
1795 if ($type & SIMPLEPIE_TYPE_ATOM_03)
1796 {
1797 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
1798 {
1799 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
1800 }
1801 }
1802 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
1803 {
1804 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
1805 {
1806 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
1807 }
1808 }
1809 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1810 {
1811 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
1812 {
1813 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
1814 }
1815 }
1816 return null;
1817 }
1818
1819 /**
1820 * Get data for an channel-level element
1821 *
1822 * This method allows you to get access to ANY element/attribute in the
1823 * channel/header section of the feed.
1824 *
1825 * See {@see SimplePie::get_feed_tags()} for a description of the return value
1826 *
1827 * @since 1.0
1828 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1829 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1830 * @param string $tag Tag name
1831 * @return array
1832 */
1833 public function get_channel_tags($namespace, $tag)
1834 {
1835 $type = $this->get_type();
1836 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
1837 {
1838 if ($return = $this->get_feed_tags($namespace, $tag))
1839 {
1840 return $return;
1841 }
1842 }
1843 if ($type & SIMPLEPIE_TYPE_RSS_10)
1844 {
1845 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
1846 {
1847 if (isset($channel[0]['child'][$namespace][$tag]))
1848 {
1849 return $channel[0]['child'][$namespace][$tag];
1850 }
1851 }
1852 }
1853 if ($type & SIMPLEPIE_TYPE_RSS_090)
1854 {
1855 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
1856 {
1857 if (isset($channel[0]['child'][$namespace][$tag]))
1858 {
1859 return $channel[0]['child'][$namespace][$tag];
1860 }
1861 }
1862 }
1863 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1864 {
1865 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
1866 {
1867 if (isset($channel[0]['child'][$namespace][$tag]))
1868 {
1869 return $channel[0]['child'][$namespace][$tag];
1870 }
1871 }
1872 }
1873 return null;
1874 }
1875
1876 /**
1877 * Get data for an channel-level element
1878 *
1879 * This method allows you to get access to ANY element/attribute in the
1880 * image/logo section of the feed.
1881 *
1882 * See {@see SimplePie::get_feed_tags()} for a description of the return value
1883 *
1884 * @since 1.0
1885 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1886 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1887 * @param string $tag Tag name
1888 * @return array
1889 */
1890 public function get_image_tags($namespace, $tag)
1891 {
1892 $type = $this->get_type();
1893 if ($type & SIMPLEPIE_TYPE_RSS_10)
1894 {
1895 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
1896 {
1897 if (isset($image[0]['child'][$namespace][$tag]))
1898 {
1899 return $image[0]['child'][$namespace][$tag];
1900 }
1901 }
1902 }
1903 if ($type & SIMPLEPIE_TYPE_RSS_090)
1904 {
1905 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
1906 {
1907 if (isset($image[0]['child'][$namespace][$tag]))
1908 {
1909 return $image[0]['child'][$namespace][$tag];
1910 }
1911 }
1912 }
1913 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1914 {
1915 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
1916 {
1917 if (isset($image[0]['child'][$namespace][$tag]))
1918 {
1919 return $image[0]['child'][$namespace][$tag];
1920 }
1921 }
1922 }
1923 return null;
1924 }
1925
1926 /**
1927 * Get the base URL value from the feed
1928 *
1929 * Uses `<xml:base>` if available, otherwise uses the first link in the
1930 * feed, or failing that, the URL of the feed itself.
1931 *
1932 * @see get_link
1933 * @see subscribe_url
1934 *
1935 * @param array $element
1936 * @return string
1937 */
1938 public function get_base($element = array())
1939 {
1940 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
1941 {
1942 return $element['xml_base'];
1943 }
1944 elseif ($this->get_link() !== null)
1945 {
1946 return $this->get_link();
1947 }
1948 else
1949 {
1950 return $this->subscribe_url();
1951 }
1952 }
1953
1954 /**
1955 * Sanitize feed data
1956 *
1957 * @access private
1958 * @see SimplePie_Sanitize::sanitize()
1959 * @param string $data Data to sanitize
1960 * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
1961 * @param string $base Base URL to resolve URLs against
1962 * @return string Sanitized data
1963 */
1964 public function sanitize($data, $type, $base = '')
1965 {
1966 return $this->sanitize->sanitize($data, $type, $base);
1967 }
1968
1969 /**
1970 * Get the title of the feed
1971 *
1972 * Uses `<atom:title>`, `<title>` or `<dc:title>`
1973 *
1974 * @since 1.0 (previously called `get_feed_title` since 0.8)
1975 * @return string|null
1976 */
1977 public function get_title()
1978 {
1979 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
1980 {
1981 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
1982 }
1983 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
1984 {
1985 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
1986 }
1987 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
1988 {
1989 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1990 }
1991 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
1992 {
1993 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1994 }
1995 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
1996 {
1997 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1998 }
1999 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2000 {
2001 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2002 }
2003 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2004 {
2005 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2006 }
2007 else
2008 {
2009 return null;
2010 }
2011 }
2012
2013 /**
2014 * Get a category for the feed
2015 *
2016 * @since Unknown
2017 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
2018 * @return SimplePie_Category|null
2019 */
2020 public function get_category($key = 0)
2021 {
2022 $categories = $this->get_categories();
2023 if (isset($categories[$key]))
2024 {
2025 return $categories[$key];
2026 }
2027 else
2028 {
2029 return null;
2030 }
2031 }
2032
2033 /**
2034 * Get all categories for the feed
2035 *
2036 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
2037 *
2038 * @since Unknown
2039 * @return array|null List of {@see SimplePie_Category} objects
2040 */
2041 public function get_categories()
2042 {
2043 $categories = array();
2044
2045 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2046 {
2047 $term = null;
2048 $scheme = null;
2049 $label = null;
2050 if (isset($category['attribs']['']['term']))
2051 {
2052 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2053 }
2054 if (isset($category['attribs']['']['scheme']))
2055 {
2056 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2057 }
2058 if (isset($category['attribs']['']['label']))
2059 {
2060 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2061 }
2062 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
2063 }
2064 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2065 {
2066 // This is really the label, but keep this as the term also for BC.
2067 // Label will also work on retrieving because that falls back to term.
2068 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2069 if (isset($category['attribs']['']['domain']))
2070 {
2071 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2072 }
2073 else
2074 {
2075 $scheme = null;
2076 }
2077 $categories[] = $this->registry->create('Category', array($term, $scheme, null));
2078 }
2079 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2080 {
2081 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2082 }
2083 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2084 {
2085 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2086 }
2087
2088 if (!empty($categories))
2089 {
2090 return array_unique($categories);
2091 }
2092 else
2093 {
2094 return null;
2095 }
2096 }
2097
2098 /**
2099 * Get an author for the feed
2100 *
2101 * @since 1.1
2102 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
2103 * @return SimplePie_Author|null
2104 */
2105 public function get_author($key = 0)
2106 {
2107 $authors = $this->get_authors();
2108 if (isset($authors[$key]))
2109 {
2110 return $authors[$key];
2111 }
2112 else
2113 {
2114 return null;
2115 }
2116 }
2117
2118 /**
2119 * Get all authors for the feed
2120 *
2121 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
2122 *
2123 * @since 1.1
2124 * @return array|null List of {@see SimplePie_Author} objects
2125 */
2126 public function get_authors()
2127 {
2128 $authors = array();
2129 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2130 {
2131 $name = null;
2132 $uri = null;
2133 $email = null;
2134 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2135 {
2136 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2137 }
2138 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2139 {
2140 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2141 }
2142 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2143 {
2144 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2145 }
2146 if ($name !== null || $email !== null || $uri !== null)
2147 {
2148 $authors[] = $this->registry->create('Author', array($name, $uri, $email));
2149 }
2150 }
2151 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2152 {
2153 $name = null;
2154 $url = null;
2155 $email = null;
2156 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2157 {
2158 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2159 }
2160 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2161 {
2162 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2163 }
2164 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2165 {
2166 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2167 }
2168 if ($name !== null || $email !== null || $url !== null)
2169 {
2170 $authors[] = $this->registry->create('Author', array($name, $url, $email));
2171 }
2172 }
2173 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2174 {
2175 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2176 }
2177 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2178 {
2179 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2180 }
2181 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2182 {
2183 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2184 }
2185
2186 if (!empty($authors))
2187 {
2188 return array_unique($authors);
2189 }
2190 else
2191 {
2192 return null;
2193 }
2194 }
2195
2196 /**
2197 * Get a contributor for the feed
2198 *
2199 * @since 1.1
2200 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
2201 * @return SimplePie_Author|null
2202 */
2203 public function get_contributor($key = 0)
2204 {
2205 $contributors = $this->get_contributors();
2206 if (isset($contributors[$key]))
2207 {
2208 return $contributors[$key];
2209 }
2210 else
2211 {
2212 return null;
2213 }
2214 }
2215
2216 /**
2217 * Get all contributors for the feed
2218 *
2219 * Uses `<atom:contributor>`
2220 *
2221 * @since 1.1
2222 * @return array|null List of {@see SimplePie_Author} objects
2223 */
2224 public function get_contributors()
2225 {
2226 $contributors = array();
2227 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2228 {
2229 $name = null;
2230 $uri = null;
2231 $email = null;
2232 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2233 {
2234 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2235 }
2236 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2237 {
2238 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2239 }
2240 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2241 {
2242 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2243 }
2244 if ($name !== null || $email !== null || $uri !== null)
2245 {
2246 $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
2247 }
2248 }
2249 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2250 {
2251 $name = null;
2252 $url = null;
2253 $email = null;
2254 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2255 {
2256 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2257 }
2258 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2259 {
2260 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2261 }
2262 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2263 {
2264 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2265 }
2266 if ($name !== null || $email !== null || $url !== null)
2267 {
2268 $contributors[] = $this->registry->create('Author', array($name, $url, $email));
2269 }
2270 }
2271
2272 if (!empty($contributors))
2273 {
2274 return array_unique($contributors);
2275 }
2276 else
2277 {
2278 return null;
2279 }
2280 }
2281
2282 /**
2283 * Get a single link for the feed
2284 *
2285 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2286 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
2287 * @param string $rel The relationship of the link to return
2288 * @return string|null Link URL
2289 */
2290 public function get_link($key = 0, $rel = 'alternate')
2291 {
2292 $links = $this->get_links($rel);
2293 if (isset($links[$key]))
2294 {
2295 return $links[$key];
2296 }
2297 else
2298 {
2299 return null;
2300 }
2301 }
2302
2303 /**
2304 * Get the permalink for the item
2305 *
2306 * Returns the first link available with a relationship of "alternate".
2307 * Identical to {@see get_link()} with key 0
2308 *
2309 * @see get_link
2310 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2311 * @internal Added for parity between the parent-level and the item/entry-level.
2312 * @return string|null Link URL
2313 */
2314 public function get_permalink()
2315 {
2316 return $this->get_link(0);
2317 }
2318
2319 /**
2320 * Get all links for the feed
2321 *
2322 * Uses `<atom:link>` or `<link>`
2323 *
2324 * @since Beta 2
2325 * @param string $rel The relationship of links to return
2326 * @return array|null Links found for the feed (strings)
2327 */
2328 public function get_links($rel = 'alternate')
2329 {
2330 if (!isset($this->data['links']))
2331 {
2332 $this->data['links'] = array();
2333 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2334 {
2335 foreach ($links as $link)
2336 {
2337 if (isset($link['attribs']['']['href']))
2338 {
2339 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2340 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2341 }
2342 }
2343 }
2344 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2345 {
2346 foreach ($links as $link)
2347 {
2348 if (isset($link['attribs']['']['href']))
2349 {
2350 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2351 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2352
2353 }
2354 }
2355 }
2356 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2357 {
2358 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2359 }
2360 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2361 {
2362 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2363 }
2364 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2365 {
2366 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2367 }
2368
2369 $keys = array_keys($this->data['links']);
2370 foreach ($keys as $key)
2371 {
2372 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
2373 {
2374 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2375 {
2376 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2377 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2378 }
2379 else
2380 {
2381 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2382 }
2383 }
2384 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2385 {
2386 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2387 }
2388 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2389 }
2390 }
2391
2392 if (isset($this->data['links'][$rel]))
2393 {
2394 return $this->data['links'][$rel];
2395 }
2396 else
2397 {
2398 return null;
2399 }
2400 }
2401
2402 public function get_all_discovered_feeds()
2403 {
2404 return $this->all_discovered_feeds;
2405 }
2406
2407 /**
2408 * Get the content for the item
2409 *
2410 * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
2411 * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
2412 *
2413 * @since 1.0 (previously called `get_feed_description()` since 0.8)
2414 * @return string|null
2415 */
2416 public function get_description()
2417 {
2418 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2419 {
2420 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2421 }
2422 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2423 {
2424 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2425 }
2426 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2427 {
2428 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2429 }
2430 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2431 {
2432 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2433 }
2434 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2435 {
2436 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2437 }
2438 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2439 {
2440 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2441 }
2442 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2443 {
2444 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2445 }
2446 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2447 {
2448 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2449 }
2450 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2451 {
2452 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2453 }
2454 else
2455 {
2456 return null;
2457 }
2458 }
2459
2460 /**
2461 * Get the copyright info for the feed
2462 *
2463 * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
2464 *
2465 * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
2466 * @return string|null
2467 */
2468 public function get_copyright()
2469 {
2470 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2471 {
2472 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2473 }
2474 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2475 {
2476 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2477 }
2478 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2479 {
2480 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2481 }
2482 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2483 {
2484 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2485 }
2486 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2487 {
2488 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2489 }
2490 else
2491 {
2492 return null;
2493 }
2494 }
2495
2496 /**
2497 * Get the language for the feed
2498 *
2499 * Uses `<language>`, `<dc:language>`, or @xml_lang
2500 *
2501 * @since 1.0 (previously called `get_feed_language()` since 0.8)
2502 * @return string|null
2503 */
2504 public function get_language()
2505 {
2506 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2507 {
2508 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2509 }
2510 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2511 {
2512 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2513 }
2514 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2515 {
2516 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2517 }
2518 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2519 {
2520 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2521 }
2522 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2523 {
2524 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2525 }
2526 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2527 {
2528 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2529 }
2530 elseif (isset($this->data['headers']['content-language']))
2531 {
2532 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2533 }
2534 else
2535 {
2536 return null;
2537 }
2538 }
2539
2540 /**
2541 * Get the latitude coordinates for the item
2542 *
2543 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2544 *
2545 * Uses `<geo:lat>` or `<georss:point>`
2546 *
2547 * @since 1.0
2548 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2549 * @link http://www.georss.org/ GeoRSS
2550 * @return string|null
2551 */
2552 public function get_latitude()
2553 {
2554
2555 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2556 {
2557 return (float) $return[0]['data'];
2558 }
2559 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2560 {
2561 return (float) $match[1];
2562 }
2563 else
2564 {
2565 return null;
2566 }
2567 }
2568
2569 /**
2570 * Get the longitude coordinates for the feed
2571 *
2572 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2573 *
2574 * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
2575 *
2576 * @since 1.0
2577 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2578 * @link http://www.georss.org/ GeoRSS
2579 * @return string|null
2580 */
2581 public function get_longitude()
2582 {
2583 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2584 {
2585 return (float) $return[0]['data'];
2586 }
2587 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2588 {
2589 return (float) $return[0]['data'];
2590 }
2591 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2592 {
2593 return (float) $match[2];
2594 }
2595 else
2596 {
2597 return null;
2598 }
2599 }
2600
2601 /**
2602 * Get the feed logo's title
2603 *
2604 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
2605 *
2606 * Uses `<image><title>` or `<image><dc:title>`
2607 *
2608 * @return string|null
2609 */
2610 public function get_image_title()
2611 {
2612 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2613 {
2614 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2615 }
2616 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2617 {
2618 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2619 }
2620 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2621 {
2622 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2623 }
2624 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2625 {
2626 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2627 }
2628 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2629 {
2630 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2631 }
2632 else
2633 {
2634 return null;
2635 }
2636 }
2637
2638 /**
2639 * Get the feed logo's URL
2640 *
2641 * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
2642 * have a "feed logo" URL. This points directly to the image itself.
2643 *
2644 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2645 * `<image><title>` or `<image><dc:title>`
2646 *
2647 * @return string|null
2648 */
2649 public function get_image_url()
2650 {
2651 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2652 {
2653 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2654 }
2655 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2656 {
2657 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2658 }
2659 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2660 {
2661 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2662 }
2663 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2664 {
2665 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2666 }
2667 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2668 {
2669 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2670 }
2671 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2672 {
2673 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2674 }
2675 else
2676 {
2677 return null;
2678 }
2679 }
2680
2681
2682 /**
2683 * Get the feed logo's link
2684 *
2685 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
2686 * points to a human-readable page that the image should link to.
2687 *
2688 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2689 * `<image><title>` or `<image><dc:title>`
2690 *
2691 * @return string|null
2692 */
2693 public function get_image_link()
2694 {
2695 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2696 {
2697 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2698 }
2699 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2700 {
2701 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2702 }
2703 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2704 {
2705 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2706 }
2707 else
2708 {
2709 return null;
2710 }
2711 }
2712
2713 /**
2714 * Get the feed logo's link
2715 *
2716 * RSS 2.0 feeds are allowed to have a "feed logo" width.
2717 *
2718 * Uses `<image><width>` or defaults to 88.0 if no width is specified and
2719 * the feed is an RSS 2.0 feed.
2720 *
2721 * @return int|float|null
2722 */
2723 public function get_image_width()
2724 {
2725 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2726 {
2727 return round($return[0]['data']);
2728 }
2729 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2730 {
2731 return 88.0;
2732 }
2733 else
2734 {
2735 return null;
2736 }
2737 }
2738
2739 /**
2740 * Get the feed logo's height
2741 *
2742 * RSS 2.0 feeds are allowed to have a "feed logo" height.
2743 *
2744 * Uses `<image><height>` or defaults to 31.0 if no height is specified and
2745 * the feed is an RSS 2.0 feed.
2746 *
2747 * @return int|float|null
2748 */
2749 public function get_image_height()
2750 {
2751 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2752 {
2753 return round($return[0]['data']);
2754 }
2755 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2756 {
2757 return 31.0;
2758 }
2759 else
2760 {
2761 return null;
2762 }
2763 }
2764
2765 /**
2766 * Get the number of items in the feed
2767 *
2768 * This is well-suited for {@link http://php.net/for for()} loops with
2769 * {@see get_item()}
2770 *
2771 * @param int $max Maximum value to return. 0 for no limit
2772 * @return int Number of items in the feed
2773 */
2774 public function get_item_quantity($max = 0)
2775 {
2776 $max = (int) $max;
2777 $qty = count($this->get_items());
2778 if ($max === 0)
2779 {
2780 return $qty;
2781 }
2782 else
2783 {
2784 return ($qty > $max) ? $max : $qty;
2785 }
2786 }
2787
2788 /**
2789 * Get a single item from the feed
2790 *
2791 * This is better suited for {@link http://php.net/for for()} loops, whereas
2792 * {@see get_items()} is better suited for
2793 * {@link http://php.net/foreach foreach()} loops.
2794 *
2795 * @see get_item_quantity()
2796 * @since Beta 2
2797 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
2798 * @return SimplePie_Item|null
2799 */
2800 public function get_item($key = 0)
2801 {
2802 $items = $this->get_items();
2803 if (isset($items[$key]))
2804 {
2805 return $items[$key];
2806 }
2807 else
2808 {
2809 return null;
2810 }
2811 }
2812
2813 /**
2814 * Get all items from the feed
2815 *
2816 * This is better suited for {@link http://php.net/for for()} loops, whereas
2817 * {@see get_items()} is better suited for
2818 * {@link http://php.net/foreach foreach()} loops.
2819 *
2820 * @see get_item_quantity
2821 * @since Beta 2
2822 * @param int $start Index to start at
2823 * @param int $end Number of items to return. 0 for all items after `$start`
2824 * @return array|null List of {@see SimplePie_Item} objects
2825 */
2826 public function get_items($start = 0, $end = 0)
2827 {
2828 if (!isset($this->data['items']))
2829 {
2830 if (!empty($this->multifeed_objects))
2831 {
2832 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2833 }
2834 else
2835 {
2836 $this->data['items'] = array();
2837 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2838 {
2839 $keys = array_keys($items);
2840 foreach ($keys as $key)
2841 {
2842 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2843 }
2844 }
2845 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2846 {
2847 $keys = array_keys($items);
2848 foreach ($keys as $key)
2849 {
2850 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2851 }
2852 }
2853 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2854 {
2855 $keys = array_keys($items);
2856 foreach ($keys as $key)
2857 {
2858 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2859 }
2860 }
2861 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2862 {
2863 $keys = array_keys($items);
2864 foreach ($keys as $key)
2865 {
2866 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2867 }
2868 }
2869 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2870 {
2871 $keys = array_keys($items);
2872 foreach ($keys as $key)
2873 {
2874 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2875 }
2876 }
2877 }
2878 }
2879
2880 if (!empty($this->data['items']))
2881 {
2882 // If we want to order it by date, check if all items have a date, and then sort it
2883 if ($this->order_by_date && empty($this->multifeed_objects))
2884 {
2885 if (!isset($this->data['ordered_items']))
2886 {
2887 $do_sort = true;
2888 foreach ($this->data['items'] as $item)
2889 {
2890 if (!$item->get_date('U'))
2891 {
2892 $do_sort = false;
2893 break;
2894 }
2895 }
2896 $item = null;
2897 $this->data['ordered_items'] = $this->data['items'];
2898 if ($do_sort)
2899 {
2900 usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
2901 }
2902 }
2903 $items = $this->data['ordered_items'];
2904 }
2905 else
2906 {
2907 $items = $this->data['items'];
2908 }
2909
2910 // Slice the data as desired
2911 if ($end === 0)
2912 {
2913 return array_slice($items, $start);
2914 }
2915 else
2916 {
2917 return array_slice($items, $start, $end);
2918 }
2919 }
2920 else
2921 {
2922 return array();
2923 }
2924 }
2925
2926 /**
2927 * Set the favicon handler
2928 *
2929 * @deprecated Use your own favicon handling instead
2930 */
2931 public function set_favicon_handler($page = false, $qs = 'i')
2932 {
2933 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2934 trigger_error('Favicon handling has been removed, please use your own handling', $level);
2935 return false;
2936 }
2937
2938 /**
2939 * Get the favicon for the current feed
2940 *
2941 * @deprecated Use your own favicon handling instead
2942 */
2943 public function get_favicon()
2944 {
2945 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2946 trigger_error('Favicon handling has been removed, please use your own handling', $level);
2947
2948 if (($url = $this->get_link()) !== null)
2949 {
2950 return 'http://g.etfv.co/' . urlencode($url);
2951 }
2952
2953 return false;
2954 }
2955
2956 /**
2957 * Magic method handler
2958 *
2959 * @param string $method Method name
2960 * @param array $args Arguments to the method
2961 * @return mixed
2962 */
2963 public function __call($method, $args)
2964 {
2965 if (strpos($method, 'subscribe_') === 0)
2966 {
2967 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2968 trigger_error('subscribe_*() has been deprecated, implement the callback yourself', $level);
2969 return '';
2970 }
2971 if ($method === 'enable_xml_dump')
2972 {
2973 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2974 trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
2975 return false;
2976 }
2977
2978 $class = get_class($this);
2979 $trace = debug_backtrace();
2980 $file = $trace[0]['file'];
2981 $line = $trace[0]['line'];
2982 trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
2983 }
2984
2985 /**
2986 * Sorting callback for items
2987 *
2988 * @access private
2989 * @param SimplePie $a
2990 * @param SimplePie $b
2991 * @return boolean
2992 */
2993 public static function sort_items($a, $b)
2994 {
2995 return $a->get_date('U') <= $b->get_date('U');
2996 }
2997
2998 /**
2999 * Merge items from several feeds into one
3000 *
3001 * If you're merging multiple feeds together, they need to all have dates
3002 * for the items or else SimplePie will refuse to sort them.
3003 *
3004 * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
3005 * @param array $urls List of SimplePie feed objects to merge
3006 * @param int $start Starting item
3007 * @param int $end Number of items to return
3008 * @param int $limit Maximum number of items per feed
3009 * @return array
3010 */
3011 public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3012 {
3013 if (is_array($urls) && sizeof($urls) > 0)
3014 {
3015 $items = array();
3016 foreach ($urls as $arg)
3017 {
3018 if ($arg instanceof SimplePie)
3019 {
3020 $items = array_merge($items, $arg->get_items(0, $limit));
3021 }
3022 else
3023 {
3024 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3025 }
3026 }
3027
3028 $do_sort = true;
3029 foreach ($items as $item)
3030 {
3031 if (!$item->get_date('U'))
3032 {
3033 $do_sort = false;
3034 break;
3035 }
3036 }
3037 $item = null;
3038 if ($do_sort)
3039 {
3040 usort($items, array(get_class($urls[0]), 'sort_items'));
3041 }
3042
3043 if ($end === 0)
3044 {
3045 return array_slice($items, $start);
3046 }
3047 else
3048 {
3049 return array_slice($items, $start, $end);
3050 }
3051 }
3052 else
3053 {
3054 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3055 return array();
3056 }
3057 }
3058}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Author.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Author.php
new file mode 100644
index 00000000..bbf3812f
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Author.php
@@ -0,0 +1,157 @@
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 * Manages all author-related data
47 *
48 * Used by {@see SimplePie_Item::get_author()} and {@see SimplePie::get_authors()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_author_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Author
56{
57 /**
58 * Author's name
59 *
60 * @var string
61 * @see get_name()
62 */
63 var $name;
64
65 /**
66 * Author's link
67 *
68 * @var string
69 * @see get_link()
70 */
71 var $link;
72
73 /**
74 * Author's email address
75 *
76 * @var string
77 * @see get_email()
78 */
79 var $email;
80
81 /**
82 * Constructor, used to input the data
83 *
84 * @param string $name
85 * @param string $link
86 * @param string $email
87 */
88 public function __construct($name = null, $link = null, $email = null)
89 {
90 $this->name = $name;
91 $this->link = $link;
92 $this->email = $email;
93 }
94
95 /**
96 * String-ified version
97 *
98 * @return string
99 */
100 public function __toString()
101 {
102 // There is no $this->data here
103 return md5(serialize($this));
104 }
105
106 /**
107 * Author's name
108 *
109 * @return string|null
110 */
111 public function get_name()
112 {
113 if ($this->name !== null)
114 {
115 return $this->name;
116 }
117 else
118 {
119 return null;
120 }
121 }
122
123 /**
124 * Author's link
125 *
126 * @return string|null
127 */
128 public function get_link()
129 {
130 if ($this->link !== null)
131 {
132 return $this->link;
133 }
134 else
135 {
136 return null;
137 }
138 }
139
140 /**
141 * Author's email address
142 *
143 * @return string|null
144 */
145 public function get_email()
146 {
147 if ($this->email !== null)
148 {
149 return $this->email;
150 }
151 else
152 {
153 return null;
154 }
155 }
156}
157
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache.php
new file mode 100644
index 00000000..75586d74
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache.php
@@ -0,0 +1,133 @@
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 to create cache objects
47 *
48 * This class can be overloaded with {@see SimplePie::set_cache_class()},
49 * although the preferred way is to create your own handler
50 * via {@see register()}
51 *
52 * @package SimplePie
53 * @subpackage Caching
54 */
55class SimplePie_Cache
56{
57 /**
58 * Cache handler classes
59 *
60 * These receive 3 parameters to their constructor, as documented in
61 * {@see register()}
62 * @var array
63 */
64 protected static $handlers = array(
65 'mysql' => 'SimplePie_Cache_MySQL',
66 'memcache' => 'SimplePie_Cache_Memcache',
67 );
68
69 /**
70 * Don't call the constructor. Please.
71 */
72 private function __construct() { }
73
74 /**
75 * Create a new SimplePie_Cache object
76 *
77 * @param string $location URL location (scheme is used to determine handler)
78 * @param string $filename Unique identifier for cache object
79 * @param string $extension 'spi' or 'spc'
80 * @return SimplePie_Cache_Base Type of object depends on scheme of `$location`
81 */
82 public static function get_handler($location, $filename, $extension)
83 {
84 $type = explode(':', $location, 2);
85 $type = $type[0];
86 if (!empty(self::$handlers[$type]))
87 {
88 $class = self::$handlers[$type];
89 return new $class($location, $filename, $extension);
90 }
91
92 return new SimplePie_Cache_File($location, $filename, $extension);
93 }
94
95 /**
96 * Create a new SimplePie_Cache object
97 *
98 * @deprecated Use {@see get_handler} instead
99 */
100 public function create($location, $filename, $extension)
101 {
102 trigger_error('Cache::create() has been replaced with Cache::get_handler(). Switch to the registry system to use this.', E_USER_DEPRECATED);
103 return self::get_handler($location, $filename, $extension);
104 }
105
106 /**
107 * Register a handler
108 *
109 * @param string $type DSN type to register for
110 * @param string $class Name of handler class. Must implement SimplePie_Cache_Base
111 */
112 public static function register($type, $class)
113 {
114 self::$handlers[$type] = $class;
115 }
116
117 /**
118 * Parse a URL into an array
119 *
120 * @param string $url
121 * @return array
122 */
123 public static function parse_URL($url)
124 {
125 $params = parse_url($url);
126 $params['extras'] = array();
127 if (isset($params['query']))
128 {
129 parse_str($params['query'], $params['extras']);
130 }
131 return $params;
132 }
133}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Base.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Base.php
new file mode 100644
index 00000000..937e3463
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Base.php
@@ -0,0 +1,114 @@
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 * Base for cache objects
47 *
48 * Classes to be used with {@see SimplePie_Cache::register()} are expected
49 * to implement this interface.
50 *
51 * @package SimplePie
52 * @subpackage Caching
53 */
54interface SimplePie_Cache_Base
55{
56 /**
57 * Feed cache type
58 *
59 * @var string
60 */
61 const TYPE_FEED = 'spc';
62
63 /**
64 * Image cache type
65 *
66 * @var string
67 */
68 const TYPE_IMAGE = 'spi';
69
70 /**
71 * Create a new cache object
72 *
73 * @param string $location Location string (from SimplePie::$cache_location)
74 * @param string $name Unique ID for the cache
75 * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
76 */
77 public function __construct($location, $name, $type);
78
79 /**
80 * Save data to the cache
81 *
82 * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
83 * @return bool Successfulness
84 */
85 public function save($data);
86
87 /**
88 * Retrieve the data saved to the cache
89 *
90 * @return array Data for SimplePie::$data
91 */
92 public function load();
93
94 /**
95 * Retrieve the last modified time for the cache
96 *
97 * @return int Timestamp
98 */
99 public function mtime();
100
101 /**
102 * Set the last modified time to the current time
103 *
104 * @return bool Success status
105 */
106 public function touch();
107
108 /**
109 * Remove the cache
110 *
111 * @return bool Success status
112 */
113 public function unlink();
114}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/DB.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/DB.php
new file mode 100644
index 00000000..ac509ae0
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/DB.php
@@ -0,0 +1,137 @@
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 * Base class for database-based caches
47 *
48 * @package SimplePie
49 * @subpackage Caching
50 */
51abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
52{
53 /**
54 * Helper for database conversion
55 *
56 * Converts a given {@see SimplePie} object into data to be stored
57 *
58 * @param SimplePie $data
59 * @return array First item is the serialized data for storage, second item is the unique ID for this item
60 */
61 protected static function prepare_simplepie_object_for_cache($data)
62 {
63 $items = $data->get_items();
64 $items_by_id = array();
65
66 if (!empty($items))
67 {
68 foreach ($items as $item)
69 {
70 $items_by_id[$item->get_id()] = $item;
71 }
72
73 if (count($items_by_id) !== count($items))
74 {
75 $items_by_id = array();
76 foreach ($items as $item)
77 {
78 $items_by_id[$item->get_id(true)] = $item;
79 }
80 }
81
82 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
83 {
84 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
85 }
86 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
87 {
88 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
89 }
90 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
91 {
92 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
93 }
94 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
95 {
96 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
97 }
98 else
99 {
100 $channel = null;
101 }
102
103 if ($channel !== null)
104 {
105 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
106 {
107 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
108 }
109 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
110 {
111 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
112 }
113 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
114 {
115 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
116 }
117 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
118 {
119 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
120 }
121 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
122 {
123 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
124 }
125 }
126 if (isset($data->data['items']))
127 {
128 unset($data->data['items']);
129 }
130 if (isset($data->data['ordered_items']))
131 {
132 unset($data->data['ordered_items']);
133 }
134 }
135 return array(serialize($data->data), $items_by_id);
136 }
137}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/File.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/File.php
new file mode 100644
index 00000000..5797b3ae
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/File.php
@@ -0,0 +1,173 @@
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 * Caches data to the filesystem
47 *
48 * @package SimplePie
49 * @subpackage Caching
50 */
51class SimplePie_Cache_File implements SimplePie_Cache_Base
52{
53 /**
54 * Location string
55 *
56 * @see SimplePie::$cache_location
57 * @var string
58 */
59 protected $location;
60
61 /**
62 * Filename
63 *
64 * @var string
65 */
66 protected $filename;
67
68 /**
69 * File extension
70 *
71 * @var string
72 */
73 protected $extension;
74
75 /**
76 * File path
77 *
78 * @var string
79 */
80 protected $name;
81
82 /**
83 * Create a new cache object
84 *
85 * @param string $location Location string (from SimplePie::$cache_location)
86 * @param string $name Unique ID for the cache
87 * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
88 */
89 public function __construct($location, $name, $type)
90 {
91 $this->location = $location;
92 $this->filename = $name;
93 $this->extension = $type;
94 $this->name = "$this->location/$this->filename.$this->extension";
95 }
96
97 /**
98 * Save data to the cache
99 *
100 * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
101 * @return bool Successfulness
102 */
103 public function save($data)
104 {
105 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
106 {
107 if ($data instanceof SimplePie)
108 {
109 $data = $data->data;
110 }
111
112 $data = serialize($data);
113 return (bool) file_put_contents($this->name, $data);
114 }
115 return false;
116 }
117
118 /**
119 * Retrieve the data saved to the cache
120 *
121 * @return array Data for SimplePie::$data
122 */
123 public function load()
124 {
125 if (file_exists($this->name) && is_readable($this->name))
126 {
127 return unserialize(file_get_contents($this->name));
128 }
129 return false;
130 }
131
132 /**
133 * Retrieve the last modified time for the cache
134 *
135 * @return int Timestamp
136 */
137 public function mtime()
138 {
139 if (file_exists($this->name))
140 {
141 return filemtime($this->name);
142 }
143 return false;
144 }
145
146 /**
147 * Set the last modified time to the current time
148 *
149 * @return bool Success status
150 */
151 public function touch()
152 {
153 if (file_exists($this->name))
154 {
155 return touch($this->name);
156 }
157 return false;
158 }
159
160 /**
161 * Remove the cache
162 *
163 * @return bool Success status
164 */
165 public function unlink()
166 {
167 if (file_exists($this->name))
168 {
169 return unlink($this->name);
170 }
171 return false;
172 }
173}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Memcache.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Memcache.php
new file mode 100644
index 00000000..fd447806
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/Memcache.php
@@ -0,0 +1,183 @@
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 * Caches data to memcache
47 *
48 * Registered for URLs with the "memcache" protocol
49 *
50 * For example, `memcache://localhost:11211/?timeout=3600&prefix=sp_` will
51 * connect to memcache on `localhost` on port 11211. All tables will be
52 * prefixed with `sp_` and data will expire after 3600 seconds
53 *
54 * @package SimplePie
55 * @subpackage Caching
56 * @uses Memcache
57 */
58class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
59{
60 /**
61 * Memcache instance
62 *
63 * @var Memcache
64 */
65 protected $cache;
66
67 /**
68 * Options
69 *
70 * @var array
71 */
72 protected $options;
73
74 /**
75 * Cache name
76 *
77 * @var string
78 */
79 protected $name;
80
81 /**
82 * Create a new cache object
83 *
84 * @param string $location Location string (from SimplePie::$cache_location)
85 * @param string $name Unique ID for the cache
86 * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
87 */
88 public function __construct($location, $name, $type)
89 {
90 $this->options = array(
91 'host' => '127.0.0.1',
92 'port' => 11211,
93 'extras' => array(
94 'timeout' => 3600, // one hour
95 'prefix' => 'simplepie_',
96 ),
97 );
98 $parsed = SimplePie_Cache::parse_URL($location);
99 $this->options['host'] = empty($parsed['host']) ? $this->options['host'] : $parsed['host'];
100 $this->options['port'] = empty($parsed['port']) ? $this->options['port'] : $parsed['port'];
101 $this->options['extras'] = array_merge($this->options['extras'], $parsed['extras']);
102 $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
103
104 $this->cache = new Memcache();
105 $this->cache->addServer($this->options['host'], (int) $this->options['port']);
106 }
107
108 /**
109 * Save data to the cache
110 *
111 * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
112 * @return bool Successfulness
113 */
114 public function save($data)
115 {
116 if ($data instanceof SimplePie)
117 {
118 $data = $data->data;
119 }
120 return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
121 }
122
123 /**
124 * Retrieve the data saved to the cache
125 *
126 * @return array Data for SimplePie::$data
127 */
128 public function load()
129 {
130 $data = $this->cache->get($this->name);
131
132 if ($data !== false)
133 {
134 return unserialize($data);
135 }
136 return false;
137 }
138
139 /**
140 * Retrieve the last modified time for the cache
141 *
142 * @return int Timestamp
143 */
144 public function mtime()
145 {
146 $data = $this->cache->get($this->name);
147
148 if ($data !== false)
149 {
150 // essentially ignore the mtime because Memcache expires on it's own
151 return time();
152 }
153
154 return false;
155 }
156
157 /**
158 * Set the last modified time to the current time
159 *
160 * @return bool Success status
161 */
162 public function touch()
163 {
164 $data = $this->cache->get($this->name);
165
166 if ($data !== false)
167 {
168 return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration);
169 }
170
171 return false;
172 }
173
174 /**
175 * Remove the cache
176 *
177 * @return bool Success status
178 */
179 public function unlink()
180 {
181 return $this->cache->delete($this->name, 0);
182 }
183}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/MySQL.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/MySQL.php
new file mode 100644
index 00000000..d53ebc11
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Cache/MySQL.php
@@ -0,0 +1,438 @@
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 * Caches data to a MySQL database
47 *
48 * Registered for URLs with the "mysql" protocol
49 *
50 * For example, `mysql://root:password@localhost:3306/mydb?prefix=sp_` will
51 * connect to the `mydb` database on `localhost` on port 3306, with the user
52 * `root` and the password `password`. All tables will be prefixed with `sp_`
53 *
54 * @package SimplePie
55 * @subpackage Caching
56 */
57class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
58{
59 /**
60 * PDO instance
61 *
62 * @var PDO
63 */
64 protected $mysql;
65
66 /**
67 * Options
68 *
69 * @var array
70 */
71 protected $options;
72
73 /**
74 * Cache ID
75 *
76 * @var string
77 */
78 protected $id;
79
80 /**
81 * Create a new cache object
82 *
83 * @param string $location Location string (from SimplePie::$cache_location)
84 * @param string $name Unique ID for the cache
85 * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
86 */
87 public function __construct($location, $name, $type)
88 {
89 $this->options = array(
90 'user' => null,
91 'pass' => null,
92 'host' => '127.0.0.1',
93 'port' => '3306',
94 'path' => '',
95 'extras' => array(
96 'prefix' => '',
97 ),
98 );
99 $this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
100
101 // Path is prefixed with a "/"
102 $this->options['dbname'] = substr($this->options['path'], 1);
103
104 try
105 {
106 $this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
107 }
108 catch (PDOException $e)
109 {
110 $this->mysql = null;
111 return;
112 }
113
114 $this->id = $name . $type;
115
116 if (!$query = $this->mysql->query('SHOW TABLES'))
117 {
118 $this->mysql = null;
119 return;
120 }
121
122 $db = array();
123 while ($row = $query->fetchColumn())
124 {
125 $db[] = $row;
126 }
127
128 if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
129 {
130 $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
131 if ($query === false)
132 {
133 $this->mysql = null;
134 }
135 }
136
137 if (!in_array($this->options['extras']['prefix'] . 'items', $db))
138 {
139 $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
140 if ($query === false)
141 {
142 $this->mysql = null;
143 }
144 }
145 }
146
147 /**
148 * Save data to the cache
149 *
150 * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
151 * @return bool Successfulness
152 */
153 public function save($data)
154 {
155 if ($this->mysql === null)
156 {
157 return false;
158 }
159
160 if ($data instanceof SimplePie)
161 {
162 $data = clone $data;
163
164 $prepared = self::prepare_simplepie_object_for_cache($data);
165
166 $query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
167 $query->bindValue(':feed', $this->id);
168 if ($query->execute())
169 {
170 if ($query->fetchColumn() > 0)
171 {
172 $items = count($prepared[1]);
173 if ($items)
174 {
175 $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
176 $query = $this->mysql->prepare($sql);
177 $query->bindValue(':items', $items);
178 }
179 else
180 {
181 $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
182 $query = $this->mysql->prepare($sql);
183 }
184
185 $query->bindValue(':data', $prepared[0]);
186 $query->bindValue(':time', time());
187 $query->bindValue(':feed', $this->id);
188 if (!$query->execute())
189 {
190 return false;
191 }
192 }
193 else
194 {
195 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
196 $query->bindValue(':feed', $this->id);
197 $query->bindValue(':count', count($prepared[1]));
198 $query->bindValue(':data', $prepared[0]);
199 $query->bindValue(':time', time());
200 if (!$query->execute())
201 {
202 return false;
203 }
204 }
205
206 $ids = array_keys($prepared[1]);
207 if (!empty($ids))
208 {
209 foreach ($ids as $id)
210 {
211 $database_ids[] = $this->mysql->quote($id);
212 }
213
214 $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
215 $query->bindValue(':feed', $this->id);
216
217 if ($query->execute())
218 {
219 $existing_ids = array();
220 while ($row = $query->fetchColumn())
221 {
222 $existing_ids[] = $row;
223 }
224
225 $new_ids = array_diff($ids, $existing_ids);
226
227 foreach ($new_ids as $new_id)
228 {
229 if (!($date = $prepared[1][$new_id]->get_date('U')))
230 {
231 $date = time();
232 }
233
234 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
235 $query->bindValue(':feed', $this->id);
236 $query->bindValue(':id', $new_id);
237 $query->bindValue(':data', serialize($prepared[1][$new_id]->data));
238 $query->bindValue(':date', $date);
239 if (!$query->execute())
240 {
241 return false;
242 }
243 }
244 return true;
245 }
246 }
247 else
248 {
249 return true;
250 }
251 }
252 }
253 else
254 {
255 $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
256 $query->bindValue(':feed', $this->id);
257 if ($query->execute())
258 {
259 if ($query->rowCount() > 0)
260 {
261 $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
262 $query->bindValue(':data', serialize($data));
263 $query->bindValue(':time', time());
264 $query->bindValue(':feed', $this->id);
265 if ($this->execute())
266 {
267 return true;
268 }
269 }
270 else
271 {
272 $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
273 $query->bindValue(':id', $this->id);
274 $query->bindValue(':data', serialize($data));
275 $query->bindValue(':time', time());
276 if ($query->execute())
277 {
278 return true;
279 }
280 }
281 }
282 }
283 return false;
284 }
285
286 /**
287 * Retrieve the data saved to the cache
288 *
289 * @return array Data for SimplePie::$data
290 */
291 public function load()
292 {
293 if ($this->mysql === null)
294 {
295 return false;
296 }
297
298 $query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
299 $query->bindValue(':id', $this->id);
300 if ($query->execute() && ($row = $query->fetch()))
301 {
302 $data = unserialize($row[1]);
303
304 if (isset($this->options['items'][0]))
305 {
306 $items = (int) $this->options['items'][0];
307 }
308 else
309 {
310 $items = (int) $row[0];
311 }
312
313 if ($items !== 0)
314 {
315 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
316 {
317 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
318 }
319 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
320 {
321 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
322 }
323 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
324 {
325 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
326 }
327 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
328 {
329 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
330 }
331 else
332 {
333 $feed = null;
334 }
335
336 if ($feed !== null)
337 {
338 $sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
339 if ($items > 0)
340 {
341 $sql .= ' LIMIT ' . $items;
342 }
343
344 $query = $this->mysql->prepare($sql);
345 $query->bindValue(':feed', $this->id);
346 if ($query->execute())
347 {
348 while ($row = $query->fetchColumn())
349 {
350 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
351 }
352 }
353 else
354 {
355 return false;
356 }
357 }
358 }
359 return $data;
360 }
361 return false;
362 }
363
364 /**
365 * Retrieve the last modified time for the cache
366 *
367 * @return int Timestamp
368 */
369 public function mtime()
370 {
371 if ($this->mysql === null)
372 {
373 return false;
374 }
375
376 $query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
377 $query->bindValue(':id', $this->id);
378 if ($query->execute() && ($time = $query->fetchColumn()))
379 {
380 return $time;
381 }
382 else
383 {
384 return false;
385 }
386 }
387
388 /**
389 * Set the last modified time to the current time
390 *
391 * @return bool Success status
392 */
393 public function touch()
394 {
395 if ($this->mysql === null)
396 {
397 return false;
398 }
399
400 $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
401 $query->bindValue(':time', time());
402 $query->bindValue(':id', $this->id);
403 if ($query->execute() && $query->rowCount() > 0)
404 {
405 return true;
406 }
407 else
408 {
409 return false;
410 }
411 }
412
413 /**
414 * Remove the cache
415 *
416 * @return bool Success status
417 */
418 public function unlink()
419 {
420 if ($this->mysql === null)
421 {
422 return false;
423 }
424
425 $query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
426 $query->bindValue(':id', $this->id);
427 $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
428 $query2->bindValue(':id', $this->id);
429 if ($query->execute() && $query2->execute())
430 {
431 return true;
432 }
433 else
434 {
435 return false;
436 }
437 }
438}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Caption.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Caption.php
new file mode 100644
index 00000000..52922c5d
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Caption.php
@@ -0,0 +1,210 @@
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/**
47 * Handles `<media:text>` captions as defined in Media RSS.
48 *
49 * Used by {@see SimplePie_Enclosure::get_caption()} and {@see SimplePie_Enclosure::get_captions()}
50 *
51 * This class can be overloaded with {@see SimplePie::set_caption_class()}
52 *
53 * @package SimplePie
54 * @subpackage API
55 */
56class SimplePie_Caption
57{
58 /**
59 * Content type
60 *
61 * @var string
62 * @see get_type()
63 */
64 var $type;
65
66 /**
67 * Language
68 *
69 * @var string
70 * @see get_language()
71 */
72 var $lang;
73
74 /**
75 * Start time
76 *
77 * @var string
78 * @see get_starttime()
79 */
80 var $startTime;
81
82 /**
83 * End time
84 *
85 * @var string
86 * @see get_endtime()
87 */
88 var $endTime;
89
90 /**
91 * Caption text
92 *
93 * @var string
94 * @see get_text()
95 */
96 var $text;
97
98 /**
99 * Constructor, used to input the data
100 *
101 * For documentation on all the parameters, see the corresponding
102 * properties and their accessors
103 */
104 public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
105 {
106 $this->type = $type;
107 $this->lang = $lang;
108 $this->startTime = $startTime;
109 $this->endTime = $endTime;
110 $this->text = $text;
111 }
112
113 /**
114 * String-ified version
115 *
116 * @return string
117 */
118 public function __toString()
119 {
120 // There is no $this->data here
121 return md5(serialize($this));
122 }
123
124 /**
125 * Get the end time
126 *
127 * @return string|null Time in the format 'hh:mm:ss.SSS'
128 */
129 public function get_endtime()
130 {
131 if ($this->endTime !== null)
132 {
133 return $this->endTime;
134 }
135 else
136 {
137 return null;
138 }
139 }
140
141 /**
142 * Get the language
143 *
144 * @link http://tools.ietf.org/html/rfc3066
145 * @return string|null Language code as per RFC 3066
146 */
147 public function get_language()
148 {
149 if ($this->lang !== null)
150 {
151 return $this->lang;
152 }
153 else
154 {
155 return null;
156 }
157 }
158
159 /**
160 * Get the start time
161 *
162 * @return string|null Time in the format 'hh:mm:ss.SSS'
163 */
164 public function get_starttime()
165 {
166 if ($this->startTime !== null)
167 {
168 return $this->startTime;
169 }
170 else
171 {
172 return null;
173 }
174 }
175
176 /**
177 * Get the text of the caption
178 *
179 * @return string|null
180 */
181 public function get_text()
182 {
183 if ($this->text !== null)
184 {
185 return $this->text;
186 }
187 else
188 {
189 return null;
190 }
191 }
192
193 /**
194 * Get the content type (not MIME type)
195 *
196 * @return string|null Either 'text' or 'html'
197 */
198 public function get_type()
199 {
200 if ($this->type !== null)
201 {
202 return $this->type;
203 }
204 else
205 {
206 return null;
207 }
208 }
209}
210
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Category.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Category.php
new file mode 100644
index 00000000..ad0407b4
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Category.php
@@ -0,0 +1,157 @@
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 * Manages all category-related data
47 *
48 * Used by {@see SimplePie_Item::get_category()} and {@see SimplePie_Item::get_categories()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_category_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Category
56{
57 /**
58 * Category identifier
59 *
60 * @var string
61 * @see get_term
62 */
63 var $term;
64
65 /**
66 * Categorization scheme identifier
67 *
68 * @var string
69 * @see get_scheme()
70 */
71 var $scheme;
72
73 /**
74 * Human readable label
75 *
76 * @var string
77 * @see get_label()
78 */
79 var $label;
80
81 /**
82 * Constructor, used to input the data
83 *
84 * @param string $term
85 * @param string $scheme
86 * @param string $label
87 */
88 public function __construct($term = null, $scheme = null, $label = null)
89 {
90 $this->term = $term;
91 $this->scheme = $scheme;
92 $this->label = $label;
93 }
94
95 /**
96 * String-ified version
97 *
98 * @return string
99 */
100 public function __toString()
101 {
102 // There is no $this->data here
103 return md5(serialize($this));
104 }
105
106 /**
107 * Get the category identifier
108 *
109 * @return string|null
110 */
111 public function get_term()
112 {
113 if ($this->term !== null)
114 {
115 return $this->term;
116 }
117 else
118 {
119 return null;
120 }
121 }
122
123 /**
124 * Get the categorization scheme identifier
125 *
126 * @return string|null
127 */
128 public function get_scheme()
129 {
130 if ($this->scheme !== null)
131 {
132 return $this->scheme;
133 }
134 else
135 {
136 return null;
137 }
138 }
139
140 /**
141 * Get the human readable label
142 *
143 * @return string|null
144 */
145 public function get_label()
146 {
147 if ($this->label !== null)
148 {
149 return $this->label;
150 }
151 else
152 {
153 return $this->get_term();
154 }
155 }
156}
157
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php
new file mode 100644
index 00000000..20d053dc
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php
@@ -0,0 +1,332 @@
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/**
47 * Content-type sniffing
48 *
49 * Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
50 *
51 * This is used since we can't always trust Content-Type headers, and is based
52 * upon the HTML5 parsing rules.
53 *
54 *
55 * This class can be overloaded with {@see SimplePie::set_content_type_sniffer_class()}
56 *
57 * @package SimplePie
58 * @subpackage HTTP
59 */
60class SimplePie_Content_Type_Sniffer
61{
62 /**
63 * File object
64 *
65 * @var SimplePie_File
66 */
67 var $file;
68
69 /**
70 * Create an instance of the class with the input file
71 *
72 * @param SimplePie_Content_Type_Sniffer $file Input file
73 */
74 public function __construct($file)
75 {
76 $this->file = $file;
77 }
78
79 /**
80 * Get the Content-Type of the specified file
81 *
82 * @return string Actual Content-Type
83 */
84 public function get_type()
85 {
86 if (isset($this->file->headers['content-type']))
87 {
88 if (!isset($this->file->headers['content-encoding'])
89 && ($this->file->headers['content-type'] === 'text/plain'
90 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
91 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
92 || $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
93 {
94 return $this->text_or_binary();
95 }
96
97 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
98 {
99 $official = substr($this->file->headers['content-type'], 0, $pos);
100 }
101 else
102 {
103 $official = $this->file->headers['content-type'];
104 }
105 $official = trim(strtolower($official));
106
107 if ($official === 'unknown/unknown'
108 || $official === 'application/unknown')
109 {
110 return $this->unknown();
111 }
112 elseif (substr($official, -4) === '+xml'
113 || $official === 'text/xml'
114 || $official === 'application/xml')
115 {
116 return $official;
117 }
118 elseif (substr($official, 0, 6) === 'image/')
119 {
120 if ($return = $this->image())
121 {
122 return $return;
123 }
124 else
125 {
126 return $official;
127 }
128 }
129 elseif ($official === 'text/html')
130 {
131 return $this->feed_or_html();
132 }
133 else
134 {
135 return $official;
136 }
137 }
138 else
139 {
140 return $this->unknown();
141 }
142 }
143
144 /**
145 * Sniff text or binary
146 *
147 * @return string Actual Content-Type
148 */
149 public function text_or_binary()
150 {
151 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
152 || substr($this->file->body, 0, 2) === "\xFF\xFE"
153 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
154 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
155 {
156 return 'text/plain';
157 }
158 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
159 {
160 return 'application/octect-stream';
161 }
162 else
163 {
164 return 'text/plain';
165 }
166 }
167
168 /**
169 * Sniff unknown
170 *
171 * @return string Actual Content-Type
172 */
173 public function unknown()
174 {
175 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
176 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
177 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
178 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
179 {
180 return 'text/html';
181 }
182 elseif (substr($this->file->body, 0, 5) === '%PDF-')
183 {
184 return 'application/pdf';
185 }
186 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
187 {
188 return 'application/postscript';
189 }
190 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
191 || substr($this->file->body, 0, 6) === 'GIF89a')
192 {
193 return 'image/gif';
194 }
195 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
196 {
197 return 'image/png';
198 }
199 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
200 {
201 return 'image/jpeg';
202 }
203 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
204 {
205 return 'image/bmp';
206 }
207 elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
208 {
209 return 'image/vnd.microsoft.icon';
210 }
211 else
212 {
213 return $this->text_or_binary();
214 }
215 }
216
217 /**
218 * Sniff images
219 *
220 * @return string Actual Content-Type
221 */
222 public function image()
223 {
224 if (substr($this->file->body, 0, 6) === 'GIF87a'
225 || substr($this->file->body, 0, 6) === 'GIF89a')
226 {
227 return 'image/gif';
228 }
229 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
230 {
231 return 'image/png';
232 }
233 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
234 {
235 return 'image/jpeg';
236 }
237 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
238 {
239 return 'image/bmp';
240 }
241 elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
242 {
243 return 'image/vnd.microsoft.icon';
244 }
245 else
246 {
247 return false;
248 }
249 }
250
251 /**
252 * Sniff HTML
253 *
254 * @return string Actual Content-Type
255 */
256 public function feed_or_html()
257 {
258 $len = strlen($this->file->body);
259 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
260
261 while ($pos < $len)
262 {
263 switch ($this->file->body[$pos])
264 {
265 case "\x09":
266 case "\x0A":
267 case "\x0D":
268 case "\x20":
269 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
270 continue 2;
271
272 case '<':
273 $pos++;
274 break;
275
276 default:
277 return 'text/html';
278 }
279
280 if (substr($this->file->body, $pos, 3) === '!--')
281 {
282 $pos += 3;
283 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
284 {
285 $pos += 3;
286 }
287 else
288 {
289 return 'text/html';
290 }
291 }
292 elseif (substr($this->file->body, $pos, 1) === '!')
293 {
294 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
295 {
296 $pos++;
297 }
298 else
299 {
300 return 'text/html';
301 }
302 }
303 elseif (substr($this->file->body, $pos, 1) === '?')
304 {
305 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
306 {
307 $pos += 2;
308 }
309 else
310 {
311 return 'text/html';
312 }
313 }
314 elseif (substr($this->file->body, $pos, 3) === 'rss'
315 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
316 {
317 return 'application/rss+xml';
318 }
319 elseif (substr($this->file->body, $pos, 4) === 'feed')
320 {
321 return 'application/atom+xml';
322 }
323 else
324 {
325 return 'text/html';
326 }
327 }
328
329 return 'text/html';
330 }
331}
332
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Copyright.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Copyright.php
new file mode 100644
index 00000000..57c535a6
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Copyright.php
@@ -0,0 +1,130 @@
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 * Manages `<media:copyright>` copyright tags as defined in Media RSS
47 *
48 * Used by {@see SimplePie_Enclosure::get_copyright()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_copyright_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Copyright
56{
57 /**
58 * Copyright URL
59 *
60 * @var string
61 * @see get_url()
62 */
63 var $url;
64
65 /**
66 * Attribution
67 *
68 * @var string
69 * @see get_attribution()
70 */
71 var $label;
72
73 /**
74 * Constructor, used to input the data
75 *
76 * For documentation on all the parameters, see the corresponding
77 * properties and their accessors
78 */
79 public function __construct($url = null, $label = null)
80 {
81 $this->url = $url;
82 $this->label = $label;
83 }
84
85 /**
86 * String-ified version
87 *
88 * @return string
89 */
90 public function __toString()
91 {
92 // There is no $this->data here
93 return md5(serialize($this));
94 }
95
96 /**
97 * Get the copyright URL
98 *
99 * @return string|null URL to copyright information
100 */
101 public function get_url()
102 {
103 if ($this->url !== null)
104 {
105 return $this->url;
106 }
107 else
108 {
109 return null;
110 }
111 }
112
113 /**
114 * Get the attribution text
115 *
116 * @return string|null
117 */
118 public function get_attribution()
119 {
120 if ($this->label !== null)
121 {
122 return $this->label;
123 }
124 else
125 {
126 return null;
127 }
128 }
129}
130
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Core.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Core.php
new file mode 100644
index 00000000..46d99662
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Core.php
@@ -0,0 +1,57 @@
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-2009, 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 * SimplePie class.
47 *
48 * Class for backward compatibility.
49 *
50 * @deprecated Use {@see SimplePie} directly
51 * @package SimplePie
52 * @subpackage API
53 */
54class SimplePie_Core extends SimplePie
55{
56
57} \ No newline at end of file
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Credit.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Credit.php
new file mode 100644
index 00000000..d3a3442a
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Credit.php
@@ -0,0 +1,156 @@
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 * Handles `<media:credit>` as defined in Media RSS
47 *
48 * Used by {@see SimplePie_Enclosure::get_credit()} and {@see SimplePie_Enclosure::get_credits()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_credit_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Credit
56{
57 /**
58 * Credited role
59 *
60 * @var string
61 * @see get_role()
62 */
63 var $role;
64
65 /**
66 * Organizational scheme
67 *
68 * @var string
69 * @see get_scheme()
70 */
71 var $scheme;
72
73 /**
74 * Credited name
75 *
76 * @var string
77 * @see get_name()
78 */
79 var $name;
80
81 /**
82 * Constructor, used to input the data
83 *
84 * For documentation on all the parameters, see the corresponding
85 * properties and their accessors
86 */
87 public function __construct($role = null, $scheme = null, $name = null)
88 {
89 $this->role = $role;
90 $this->scheme = $scheme;
91 $this->name = $name;
92 }
93
94 /**
95 * String-ified version
96 *
97 * @return string
98 */
99 public function __toString()
100 {
101 // There is no $this->data here
102 return md5(serialize($this));
103 }
104
105 /**
106 * Get the role of the person receiving credit
107 *
108 * @return string|null
109 */
110 public function get_role()
111 {
112 if ($this->role !== null)
113 {
114 return $this->role;
115 }
116 else
117 {
118 return null;
119 }
120 }
121
122 /**
123 * Get the organizational scheme
124 *
125 * @return string|null
126 */
127 public function get_scheme()
128 {
129 if ($this->scheme !== null)
130 {
131 return $this->scheme;
132 }
133 else
134 {
135 return null;
136 }
137 }
138
139 /**
140 * Get the credited person/entity's name
141 *
142 * @return string|null
143 */
144 public function get_name()
145 {
146 if ($this->name !== null)
147 {
148 return $this->name;
149 }
150 else
151 {
152 return null;
153 }
154 }
155}
156
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php
new file mode 100644
index 00000000..069e8d8e
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php
@@ -0,0 +1,617 @@
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/**
47 * Decode HTML Entities
48 *
49 * This implements HTML5 as of revision 967 (2007-06-28)
50 *
51 * @deprecated Use DOMDocument instead!
52 * @package SimplePie
53 */
54class SimplePie_Decode_HTML_Entities
55{
56 /**
57 * Data to be parsed
58 *
59 * @access private
60 * @var string
61 */
62 var $data = '';
63
64 /**
65 * Currently consumed bytes
66 *
67 * @access private
68 * @var string
69 */
70 var $consumed = '';
71
72 /**
73 * Position of the current byte being parsed
74 *
75 * @access private
76 * @var int
77 */
78 var $position = 0;
79
80 /**
81 * Create an instance of the class with the input data
82 *
83 * @access public
84 * @param string $data Input data
85 */
86 public function __construct($data)
87 {
88 $this->data = $data;
89 }
90
91 /**
92 * Parse the input data
93 *
94 * @access public
95 * @return string Output data
96 */
97 public function parse()
98 {
99 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
100 {
101 $this->consume();
102 $this->entity();
103 $this->consumed = '';
104 }
105 return $this->data;
106 }
107
108 /**
109 * Consume the next byte
110 *
111 * @access private
112 * @return mixed The next byte, or false, if there is no more data
113 */
114 public function consume()
115 {
116 if (isset($this->data[$this->position]))
117 {
118 $this->consumed .= $this->data[$this->position];
119 return $this->data[$this->position++];
120 }
121 else
122 {
123 return false;
124 }
125 }
126
127 /**
128 * Consume a range of characters
129 *
130 * @access private
131 * @param string $chars Characters to consume
132 * @return mixed A series of characters that match the range, or false
133 */
134 public function consume_range($chars)
135 {
136 if ($len = strspn($this->data, $chars, $this->position))
137 {
138 $data = substr($this->data, $this->position, $len);
139 $this->consumed .= $data;
140 $this->position += $len;
141 return $data;
142 }
143 else
144 {
145 return false;
146 }
147 }
148
149 /**
150 * Unconsume one byte
151 *
152 * @access private
153 */
154 public function unconsume()
155 {
156 $this->consumed = substr($this->consumed, 0, -1);
157 $this->position--;
158 }
159
160 /**
161 * Decode an entity
162 *
163 * @access private
164 */
165 public function entity()
166 {
167 switch ($this->consume())
168 {
169 case "\x09":
170 case "\x0A":
171 case "\x0B":
172 case "\x0B":
173 case "\x0C":
174 case "\x20":
175 case "\x3C":
176 case "\x26":
177 case false:
178 break;
179
180 case "\x23":
181 switch ($this->consume())
182 {
183 case "\x78":
184 case "\x58":
185 $range = '0123456789ABCDEFabcdef';
186 $hex = true;
187 break;
188
189 default:
190 $range = '0123456789';
191 $hex = false;
192 $this->unconsume();
193 break;
194 }
195
196 if ($codepoint = $this->consume_range($range))
197 {
198 static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
199
200 if ($hex)
201 {
202 $codepoint = hexdec($codepoint);
203 }
204 else
205 {
206 $codepoint = intval($codepoint);
207 }
208
209 if (isset($windows_1252_specials[$codepoint]))
210 {
211 $replacement = $windows_1252_specials[$codepoint];
212 }
213 else
214 {
215 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
216 }
217
218 if (!in_array($this->consume(), array(';', false), true))
219 {
220 $this->unconsume();
221 }
222
223 $consumed_length = strlen($this->consumed);
224 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
225 $this->position += strlen($replacement) - $consumed_length;
226 }
227 break;
228
229 default:
230 static $entities = array(
231 'Aacute' => "\xC3\x81",
232 'aacute' => "\xC3\xA1",
233 'Aacute;' => "\xC3\x81",
234 'aacute;' => "\xC3\xA1",
235 'Acirc' => "\xC3\x82",
236 'acirc' => "\xC3\xA2",
237 'Acirc;' => "\xC3\x82",
238 'acirc;' => "\xC3\xA2",
239 'acute' => "\xC2\xB4",
240 'acute;' => "\xC2\xB4",
241 'AElig' => "\xC3\x86",
242 'aelig' => "\xC3\xA6",
243 'AElig;' => "\xC3\x86",
244 'aelig;' => "\xC3\xA6",
245 'Agrave' => "\xC3\x80",
246 'agrave' => "\xC3\xA0",
247 'Agrave;' => "\xC3\x80",
248 'agrave;' => "\xC3\xA0",
249 'alefsym;' => "\xE2\x84\xB5",
250 'Alpha;' => "\xCE\x91",
251 'alpha;' => "\xCE\xB1",
252 'AMP' => "\x26",
253 'amp' => "\x26",
254 'AMP;' => "\x26",
255 'amp;' => "\x26",
256 'and;' => "\xE2\x88\xA7",
257 'ang;' => "\xE2\x88\xA0",
258 'apos;' => "\x27",
259 'Aring' => "\xC3\x85",
260 'aring' => "\xC3\xA5",
261 'Aring;' => "\xC3\x85",
262 'aring;' => "\xC3\xA5",
263 'asymp;' => "\xE2\x89\x88",
264 'Atilde' => "\xC3\x83",
265 'atilde' => "\xC3\xA3",
266 'Atilde;' => "\xC3\x83",
267 'atilde;' => "\xC3\xA3",
268 'Auml' => "\xC3\x84",
269 'auml' => "\xC3\xA4",
270 'Auml;' => "\xC3\x84",
271 'auml;' => "\xC3\xA4",
272 'bdquo;' => "\xE2\x80\x9E",
273 'Beta;' => "\xCE\x92",
274 'beta;' => "\xCE\xB2",
275 'brvbar' => "\xC2\xA6",
276 'brvbar;' => "\xC2\xA6",
277 'bull;' => "\xE2\x80\xA2",
278 'cap;' => "\xE2\x88\xA9",
279 'Ccedil' => "\xC3\x87",
280 'ccedil' => "\xC3\xA7",
281 'Ccedil;' => "\xC3\x87",
282 'ccedil;' => "\xC3\xA7",
283 'cedil' => "\xC2\xB8",
284 'cedil;' => "\xC2\xB8",
285 'cent' => "\xC2\xA2",
286 'cent;' => "\xC2\xA2",
287 'Chi;' => "\xCE\xA7",
288 'chi;' => "\xCF\x87",
289 'circ;' => "\xCB\x86",
290 'clubs;' => "\xE2\x99\xA3",
291 'cong;' => "\xE2\x89\x85",
292 'COPY' => "\xC2\xA9",
293 'copy' => "\xC2\xA9",
294 'COPY;' => "\xC2\xA9",
295 'copy;' => "\xC2\xA9",
296 'crarr;' => "\xE2\x86\xB5",
297 'cup;' => "\xE2\x88\xAA",
298 'curren' => "\xC2\xA4",
299 'curren;' => "\xC2\xA4",
300 'Dagger;' => "\xE2\x80\xA1",
301 'dagger;' => "\xE2\x80\xA0",
302 'dArr;' => "\xE2\x87\x93",
303 'darr;' => "\xE2\x86\x93",
304 'deg' => "\xC2\xB0",
305 'deg;' => "\xC2\xB0",
306 'Delta;' => "\xCE\x94",
307 'delta;' => "\xCE\xB4",
308 'diams;' => "\xE2\x99\xA6",
309 'divide' => "\xC3\xB7",
310 'divide;' => "\xC3\xB7",
311 'Eacute' => "\xC3\x89",
312 'eacute' => "\xC3\xA9",
313 'Eacute;' => "\xC3\x89",
314 'eacute;' => "\xC3\xA9",
315 'Ecirc' => "\xC3\x8A",
316 'ecirc' => "\xC3\xAA",
317 'Ecirc;' => "\xC3\x8A",
318 'ecirc;' => "\xC3\xAA",
319 'Egrave' => "\xC3\x88",
320 'egrave' => "\xC3\xA8",
321 'Egrave;' => "\xC3\x88",
322 'egrave;' => "\xC3\xA8",
323 'empty;' => "\xE2\x88\x85",
324 'emsp;' => "\xE2\x80\x83",
325 'ensp;' => "\xE2\x80\x82",
326 'Epsilon;' => "\xCE\x95",
327 'epsilon;' => "\xCE\xB5",
328 'equiv;' => "\xE2\x89\xA1",
329 'Eta;' => "\xCE\x97",
330 'eta;' => "\xCE\xB7",
331 'ETH' => "\xC3\x90",
332 'eth' => "\xC3\xB0",
333 'ETH;' => "\xC3\x90",
334 'eth;' => "\xC3\xB0",
335 'Euml' => "\xC3\x8B",
336 'euml' => "\xC3\xAB",
337 'Euml;' => "\xC3\x8B",
338 'euml;' => "\xC3\xAB",
339 'euro;' => "\xE2\x82\xAC",
340 'exist;' => "\xE2\x88\x83",
341 'fnof;' => "\xC6\x92",
342 'forall;' => "\xE2\x88\x80",
343 'frac12' => "\xC2\xBD",
344 'frac12;' => "\xC2\xBD",
345 'frac14' => "\xC2\xBC",
346 'frac14;' => "\xC2\xBC",
347 'frac34' => "\xC2\xBE",
348 'frac34;' => "\xC2\xBE",
349 'frasl;' => "\xE2\x81\x84",
350 'Gamma;' => "\xCE\x93",
351 'gamma;' => "\xCE\xB3",
352 'ge;' => "\xE2\x89\xA5",
353 'GT' => "\x3E",
354 'gt' => "\x3E",
355 'GT;' => "\x3E",
356 'gt;' => "\x3E",
357 'hArr;' => "\xE2\x87\x94",
358 'harr;' => "\xE2\x86\x94",
359 'hearts;' => "\xE2\x99\xA5",
360 'hellip;' => "\xE2\x80\xA6",
361 'Iacute' => "\xC3\x8D",
362 'iacute' => "\xC3\xAD",
363 'Iacute;' => "\xC3\x8D",
364 'iacute;' => "\xC3\xAD",
365 'Icirc' => "\xC3\x8E",
366 'icirc' => "\xC3\xAE",
367 'Icirc;' => "\xC3\x8E",
368 'icirc;' => "\xC3\xAE",
369 'iexcl' => "\xC2\xA1",
370 'iexcl;' => "\xC2\xA1",
371 'Igrave' => "\xC3\x8C",
372 'igrave' => "\xC3\xAC",
373 'Igrave;' => "\xC3\x8C",
374 'igrave;' => "\xC3\xAC",
375 'image;' => "\xE2\x84\x91",
376 'infin;' => "\xE2\x88\x9E",
377 'int;' => "\xE2\x88\xAB",
378 'Iota;' => "\xCE\x99",
379 'iota;' => "\xCE\xB9",
380 'iquest' => "\xC2\xBF",
381 'iquest;' => "\xC2\xBF",
382 'isin;' => "\xE2\x88\x88",
383 'Iuml' => "\xC3\x8F",
384 'iuml' => "\xC3\xAF",
385 'Iuml;' => "\xC3\x8F",
386 'iuml;' => "\xC3\xAF",
387 'Kappa;' => "\xCE\x9A",
388 'kappa;' => "\xCE\xBA",
389 'Lambda;' => "\xCE\x9B",
390 'lambda;' => "\xCE\xBB",
391 'lang;' => "\xE3\x80\x88",
392 'laquo' => "\xC2\xAB",
393 'laquo;' => "\xC2\xAB",
394 'lArr;' => "\xE2\x87\x90",
395 'larr;' => "\xE2\x86\x90",
396 'lceil;' => "\xE2\x8C\x88",
397 'ldquo;' => "\xE2\x80\x9C",
398 'le;' => "\xE2\x89\xA4",
399 'lfloor;' => "\xE2\x8C\x8A",
400 'lowast;' => "\xE2\x88\x97",
401 'loz;' => "\xE2\x97\x8A",
402 'lrm;' => "\xE2\x80\x8E",
403 'lsaquo;' => "\xE2\x80\xB9",
404 'lsquo;' => "\xE2\x80\x98",
405 'LT' => "\x3C",
406 'lt' => "\x3C",
407 'LT;' => "\x3C",
408 'lt;' => "\x3C",
409 'macr' => "\xC2\xAF",
410 'macr;' => "\xC2\xAF",
411 'mdash;' => "\xE2\x80\x94",
412 'micro' => "\xC2\xB5",
413 'micro;' => "\xC2\xB5",
414 'middot' => "\xC2\xB7",
415 'middot;' => "\xC2\xB7",
416 'minus;' => "\xE2\x88\x92",
417 'Mu;' => "\xCE\x9C",
418 'mu;' => "\xCE\xBC",
419 'nabla;' => "\xE2\x88\x87",
420 'nbsp' => "\xC2\xA0",
421 'nbsp;' => "\xC2\xA0",
422 'ndash;' => "\xE2\x80\x93",
423 'ne;' => "\xE2\x89\xA0",
424 'ni;' => "\xE2\x88\x8B",
425 'not' => "\xC2\xAC",
426 'not;' => "\xC2\xAC",
427 'notin;' => "\xE2\x88\x89",
428 'nsub;' => "\xE2\x8A\x84",
429 'Ntilde' => "\xC3\x91",
430 'ntilde' => "\xC3\xB1",
431 'Ntilde;' => "\xC3\x91",
432 'ntilde;' => "\xC3\xB1",
433 'Nu;' => "\xCE\x9D",
434 'nu;' => "\xCE\xBD",
435 'Oacute' => "\xC3\x93",
436 'oacute' => "\xC3\xB3",
437 'Oacute;' => "\xC3\x93",
438 'oacute;' => "\xC3\xB3",
439 'Ocirc' => "\xC3\x94",
440 'ocirc' => "\xC3\xB4",
441 'Ocirc;' => "\xC3\x94",
442 'ocirc;' => "\xC3\xB4",
443 'OElig;' => "\xC5\x92",
444 'oelig;' => "\xC5\x93",
445 'Ograve' => "\xC3\x92",
446 'ograve' => "\xC3\xB2",
447 'Ograve;' => "\xC3\x92",
448 'ograve;' => "\xC3\xB2",
449 'oline;' => "\xE2\x80\xBE",
450 'Omega;' => "\xCE\xA9",
451 'omega;' => "\xCF\x89",
452 'Omicron;' => "\xCE\x9F",
453 'omicron;' => "\xCE\xBF",
454 'oplus;' => "\xE2\x8A\x95",
455 'or;' => "\xE2\x88\xA8",
456 'ordf' => "\xC2\xAA",
457 'ordf;' => "\xC2\xAA",
458 'ordm' => "\xC2\xBA",
459 'ordm;' => "\xC2\xBA",
460 'Oslash' => "\xC3\x98",
461 'oslash' => "\xC3\xB8",
462 'Oslash;' => "\xC3\x98",
463 'oslash;' => "\xC3\xB8",
464 'Otilde' => "\xC3\x95",
465 'otilde' => "\xC3\xB5",
466 'Otilde;' => "\xC3\x95",
467 'otilde;' => "\xC3\xB5",
468 'otimes;' => "\xE2\x8A\x97",
469 'Ouml' => "\xC3\x96",
470 'ouml' => "\xC3\xB6",
471 'Ouml;' => "\xC3\x96",
472 'ouml;' => "\xC3\xB6",
473 'para' => "\xC2\xB6",
474 'para;' => "\xC2\xB6",
475 'part;' => "\xE2\x88\x82",
476 'permil;' => "\xE2\x80\xB0",
477 'perp;' => "\xE2\x8A\xA5",
478 'Phi;' => "\xCE\xA6",
479 'phi;' => "\xCF\x86",
480 'Pi;' => "\xCE\xA0",
481 'pi;' => "\xCF\x80",
482 'piv;' => "\xCF\x96",
483 'plusmn' => "\xC2\xB1",
484 'plusmn;' => "\xC2\xB1",
485 'pound' => "\xC2\xA3",
486 'pound;' => "\xC2\xA3",
487 'Prime;' => "\xE2\x80\xB3",
488 'prime;' => "\xE2\x80\xB2",
489 'prod;' => "\xE2\x88\x8F",
490 'prop;' => "\xE2\x88\x9D",
491 'Psi;' => "\xCE\xA8",
492 'psi;' => "\xCF\x88",
493 'QUOT' => "\x22",
494 'quot' => "\x22",
495 'QUOT;' => "\x22",
496 'quot;' => "\x22",
497 'radic;' => "\xE2\x88\x9A",
498 'rang;' => "\xE3\x80\x89",
499 'raquo' => "\xC2\xBB",
500 'raquo;' => "\xC2\xBB",
501 'rArr;' => "\xE2\x87\x92",
502 'rarr;' => "\xE2\x86\x92",
503 'rceil;' => "\xE2\x8C\x89",
504 'rdquo;' => "\xE2\x80\x9D",
505 'real;' => "\xE2\x84\x9C",
506 'REG' => "\xC2\xAE",
507 'reg' => "\xC2\xAE",
508 'REG;' => "\xC2\xAE",
509 'reg;' => "\xC2\xAE",
510 'rfloor;' => "\xE2\x8C\x8B",
511 'Rho;' => "\xCE\xA1",
512 'rho;' => "\xCF\x81",
513 'rlm;' => "\xE2\x80\x8F",
514 'rsaquo;' => "\xE2\x80\xBA",
515 'rsquo;' => "\xE2\x80\x99",
516 'sbquo;' => "\xE2\x80\x9A",
517 'Scaron;' => "\xC5\xA0",
518 'scaron;' => "\xC5\xA1",
519 'sdot;' => "\xE2\x8B\x85",
520 'sect' => "\xC2\xA7",
521 'sect;' => "\xC2\xA7",
522 'shy' => "\xC2\xAD",
523 'shy;' => "\xC2\xAD",
524 'Sigma;' => "\xCE\xA3",
525 'sigma;' => "\xCF\x83",
526 'sigmaf;' => "\xCF\x82",
527 'sim;' => "\xE2\x88\xBC",
528 'spades;' => "\xE2\x99\xA0",
529 'sub;' => "\xE2\x8A\x82",
530 'sube;' => "\xE2\x8A\x86",
531 'sum;' => "\xE2\x88\x91",
532 'sup;' => "\xE2\x8A\x83",
533 'sup1' => "\xC2\xB9",
534 'sup1;' => "\xC2\xB9",
535 'sup2' => "\xC2\xB2",
536 'sup2;' => "\xC2\xB2",
537 'sup3' => "\xC2\xB3",
538 'sup3;' => "\xC2\xB3",
539 'supe;' => "\xE2\x8A\x87",
540 'szlig' => "\xC3\x9F",
541 'szlig;' => "\xC3\x9F",
542 'Tau;' => "\xCE\xA4",
543 'tau;' => "\xCF\x84",
544 'there4;' => "\xE2\x88\xB4",
545 'Theta;' => "\xCE\x98",
546 'theta;' => "\xCE\xB8",
547 'thetasym;' => "\xCF\x91",
548 'thinsp;' => "\xE2\x80\x89",
549 'THORN' => "\xC3\x9E",
550 'thorn' => "\xC3\xBE",
551 'THORN;' => "\xC3\x9E",
552 'thorn;' => "\xC3\xBE",
553 'tilde;' => "\xCB\x9C",
554 'times' => "\xC3\x97",
555 'times;' => "\xC3\x97",
556 'TRADE;' => "\xE2\x84\xA2",
557 'trade;' => "\xE2\x84\xA2",
558 'Uacute' => "\xC3\x9A",
559 'uacute' => "\xC3\xBA",
560 'Uacute;' => "\xC3\x9A",
561 'uacute;' => "\xC3\xBA",
562 'uArr;' => "\xE2\x87\x91",
563 'uarr;' => "\xE2\x86\x91",
564 'Ucirc' => "\xC3\x9B",
565 'ucirc' => "\xC3\xBB",
566 'Ucirc;' => "\xC3\x9B",
567 'ucirc;' => "\xC3\xBB",
568 'Ugrave' => "\xC3\x99",
569 'ugrave' => "\xC3\xB9",
570 'Ugrave;' => "\xC3\x99",
571 'ugrave;' => "\xC3\xB9",
572 'uml' => "\xC2\xA8",
573 'uml;' => "\xC2\xA8",
574 'upsih;' => "\xCF\x92",
575 'Upsilon;' => "\xCE\xA5",
576 'upsilon;' => "\xCF\x85",
577 'Uuml' => "\xC3\x9C",
578 'uuml' => "\xC3\xBC",
579 'Uuml;' => "\xC3\x9C",
580 'uuml;' => "\xC3\xBC",
581 'weierp;' => "\xE2\x84\x98",
582 'Xi;' => "\xCE\x9E",
583 'xi;' => "\xCE\xBE",
584 'Yacute' => "\xC3\x9D",
585 'yacute' => "\xC3\xBD",
586 'Yacute;' => "\xC3\x9D",
587 'yacute;' => "\xC3\xBD",
588 'yen' => "\xC2\xA5",
589 'yen;' => "\xC2\xA5",
590 'yuml' => "\xC3\xBF",
591 'Yuml;' => "\xC5\xB8",
592 'yuml;' => "\xC3\xBF",
593 'Zeta;' => "\xCE\x96",
594 'zeta;' => "\xCE\xB6",
595 'zwj;' => "\xE2\x80\x8D",
596 'zwnj;' => "\xE2\x80\x8C"
597 );
598
599 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
600 {
601 $consumed = substr($this->consumed, 1);
602 if (isset($entities[$consumed]))
603 {
604 $match = $consumed;
605 }
606 }
607
608 if ($match !== null)
609 {
610 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
611 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
612 }
613 break;
614 }
615 }
616}
617
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Enclosure.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Enclosure.php
new file mode 100644
index 00000000..55674379
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Enclosure.php
@@ -0,0 +1,1380 @@
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 * Handles everything related to enclosures (including Media RSS and iTunes RSS)
47 *
48 * Used by {@see SimplePie_Item::get_enclosure()} and {@see SimplePie_Item::get_enclosures()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_enclosure_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Enclosure
56{
57 /**
58 * @var string
59 * @see get_bitrate()
60 */
61 var $bitrate;
62
63 /**
64 * @var array
65 * @see get_captions()
66 */
67 var $captions;
68
69 /**
70 * @var array
71 * @see get_categories()
72 */
73 var $categories;
74
75 /**
76 * @var int
77 * @see get_channels()
78 */
79 var $channels;
80
81 /**
82 * @var SimplePie_Copyright
83 * @see get_copyright()
84 */
85 var $copyright;
86
87 /**
88 * @var array
89 * @see get_credits()
90 */
91 var $credits;
92
93 /**
94 * @var string
95 * @see get_description()
96 */
97 var $description;
98
99 /**
100 * @var int
101 * @see get_duration()
102 */
103 var $duration;
104
105 /**
106 * @var string
107 * @see get_expression()
108 */
109 var $expression;
110
111 /**
112 * @var string
113 * @see get_framerate()
114 */
115 var $framerate;
116
117 /**
118 * @var string
119 * @see get_handler()
120 */
121 var $handler;
122
123 /**
124 * @var array
125 * @see get_hashes()
126 */
127 var $hashes;
128
129 /**
130 * @var string
131 * @see get_height()
132 */
133 var $height;
134
135 /**
136 * @deprecated
137 * @var null
138 */
139 var $javascript;
140
141 /**
142 * @var array
143 * @see get_keywords()
144 */
145 var $keywords;
146
147 /**
148 * @var string
149 * @see get_language()
150 */
151 var $lang;
152
153 /**
154 * @var string
155 * @see get_length()
156 */
157 var $length;
158
159 /**
160 * @var string
161 * @see get_link()
162 */
163 var $link;
164
165 /**
166 * @var string
167 * @see get_medium()
168 */
169 var $medium;
170
171 /**
172 * @var string
173 * @see get_player()
174 */
175 var $player;
176
177 /**
178 * @var array
179 * @see get_ratings()
180 */
181 var $ratings;
182
183 /**
184 * @var array
185 * @see get_restrictions()
186 */
187 var $restrictions;
188
189 /**
190 * @var string
191 * @see get_sampling_rate()
192 */
193 var $samplingrate;
194
195 /**
196 * @var array
197 * @see get_thumbnails()
198 */
199 var $thumbnails;
200
201 /**
202 * @var string
203 * @see get_title()
204 */
205 var $title;
206
207 /**
208 * @var string
209 * @see get_type()
210 */
211 var $type;
212
213 /**
214 * @var string
215 * @see get_width()
216 */
217 var $width;
218
219 /**
220 * Constructor, used to input the data
221 *
222 * For documentation on all the parameters, see the corresponding
223 * properties and their accessors
224 *
225 * @uses idna_convert If available, this will convert an IDN
226 */
227 public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
228 {
229 $this->bitrate = $bitrate;
230 $this->captions = $captions;
231 $this->categories = $categories;
232 $this->channels = $channels;
233 $this->copyright = $copyright;
234 $this->credits = $credits;
235 $this->description = $description;
236 $this->duration = $duration;
237 $this->expression = $expression;
238 $this->framerate = $framerate;
239 $this->hashes = $hashes;
240 $this->height = $height;
241 $this->keywords = $keywords;
242 $this->lang = $lang;
243 $this->length = $length;
244 $this->link = $link;
245 $this->medium = $medium;
246 $this->player = $player;
247 $this->ratings = $ratings;
248 $this->restrictions = $restrictions;
249 $this->samplingrate = $samplingrate;
250 $this->thumbnails = $thumbnails;
251 $this->title = $title;
252 $this->type = $type;
253 $this->width = $width;
254
255 if (class_exists('idna_convert'))
256 {
257 $idn = new idna_convert();
258 $parsed = SimplePie_Misc::parse_url($link);
259 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
260 }
261 $this->handler = $this->get_handler(); // Needs to load last
262 }
263
264 /**
265 * String-ified version
266 *
267 * @return string
268 */
269 public function __toString()
270 {
271 // There is no $this->data here
272 return md5(serialize($this));
273 }
274
275 /**
276 * Get the bitrate
277 *
278 * @return string|null
279 */
280 public function get_bitrate()
281 {
282 if ($this->bitrate !== null)
283 {
284 return $this->bitrate;
285 }
286 else
287 {
288 return null;
289 }
290 }
291
292 /**
293 * Get a single caption
294 *
295 * @param int $key
296 * @return SimplePie_Caption|null
297 */
298 public function get_caption($key = 0)
299 {
300 $captions = $this->get_captions();
301 if (isset($captions[$key]))
302 {
303 return $captions[$key];
304 }
305 else
306 {
307 return null;
308 }
309 }
310
311 /**
312 * Get all captions
313 *
314 * @return array|null Array of {@see SimplePie_Caption} objects
315 */
316 public function get_captions()
317 {
318 if ($this->captions !== null)
319 {
320 return $this->captions;
321 }
322 else
323 {
324 return null;
325 }
326 }
327
328 /**
329 * Get a single category
330 *
331 * @param int $key
332 * @return SimplePie_Category|null
333 */
334 public function get_category($key = 0)
335 {
336 $categories = $this->get_categories();
337 if (isset($categories[$key]))
338 {
339 return $categories[$key];
340 }
341 else
342 {
343 return null;
344 }
345 }
346
347 /**
348 * Get all categories
349 *
350 * @return array|null Array of {@see SimplePie_Category} objects
351 */
352 public function get_categories()
353 {
354 if ($this->categories !== null)
355 {
356 return $this->categories;
357 }
358 else
359 {
360 return null;
361 }
362 }
363
364 /**
365 * Get the number of audio channels
366 *
367 * @return int|null
368 */
369 public function get_channels()
370 {
371 if ($this->channels !== null)
372 {
373 return $this->channels;
374 }
375 else
376 {
377 return null;
378 }
379 }
380
381 /**
382 * Get the copyright information
383 *
384 * @return SimplePie_Copyright|null
385 */
386 public function get_copyright()
387 {
388 if ($this->copyright !== null)
389 {
390 return $this->copyright;
391 }
392 else
393 {
394 return null;
395 }
396 }
397
398 /**
399 * Get a single credit
400 *
401 * @param int $key
402 * @return SimplePie_Credit|null
403 */
404 public function get_credit($key = 0)
405 {
406 $credits = $this->get_credits();
407 if (isset($credits[$key]))
408 {
409 return $credits[$key];
410 }
411 else
412 {
413 return null;
414 }
415 }
416
417 /**
418 * Get all credits
419 *
420 * @return array|null Array of {@see SimplePie_Credit} objects
421 */
422 public function get_credits()
423 {
424 if ($this->credits !== null)
425 {
426 return $this->credits;
427 }
428 else
429 {
430 return null;
431 }
432 }
433
434 /**
435 * Get the description of the enclosure
436 *
437 * @return string|null
438 */
439 public function get_description()
440 {
441 if ($this->description !== null)
442 {
443 return $this->description;
444 }
445 else
446 {
447 return null;
448 }
449 }
450
451 /**
452 * Get the duration of the enclosure
453 *
454 * @param string $convert Convert seconds into hh:mm:ss
455 * @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found)
456 */
457 public function get_duration($convert = false)
458 {
459 if ($this->duration !== null)
460 {
461 if ($convert)
462 {
463 $time = SimplePie_Misc::time_hms($this->duration);
464 return $time;
465 }
466 else
467 {
468 return $this->duration;
469 }
470 }
471 else
472 {
473 return null;
474 }
475 }
476
477 /**
478 * Get the expression
479 *
480 * @return string Probably one of 'sample', 'full', 'nonstop', 'clip'. Defaults to 'full'
481 */
482 public function get_expression()
483 {
484 if ($this->expression !== null)
485 {
486 return $this->expression;
487 }
488 else
489 {
490 return 'full';
491 }
492 }
493
494 /**
495 * Get the file extension
496 *
497 * @return string|null
498 */
499 public function get_extension()
500 {
501 if ($this->link !== null)
502 {
503 $url = SimplePie_Misc::parse_url($this->link);
504 if ($url['path'] !== '')
505 {
506 return pathinfo($url['path'], PATHINFO_EXTENSION);
507 }
508 }
509 return null;
510 }
511
512 /**
513 * Get the framerate (in frames-per-second)
514 *
515 * @return string|null
516 */
517 public function get_framerate()
518 {
519 if ($this->framerate !== null)
520 {
521 return $this->framerate;
522 }
523 else
524 {
525 return null;
526 }
527 }
528
529 /**
530 * Get the preferred handler
531 *
532 * @return string|null One of 'flash', 'fmedia', 'quicktime', 'wmedia', 'mp3'
533 */
534 public function get_handler()
535 {
536 return $this->get_real_type(true);
537 }
538
539 /**
540 * Get a single hash
541 *
542 * @link http://www.rssboard.org/media-rss#media-hash
543 * @param int $key
544 * @return string|null Hash as per `media:hash`, prefixed with "$algo:"
545 */
546 public function get_hash($key = 0)
547 {
548 $hashes = $this->get_hashes();
549 if (isset($hashes[$key]))
550 {
551 return $hashes[$key];
552 }
553 else
554 {
555 return null;
556 }
557 }
558
559 /**
560 * Get all credits
561 *
562 * @return array|null Array of strings, see {@see get_hash()}
563 */
564 public function get_hashes()
565 {
566 if ($this->hashes !== null)
567 {
568 return $this->hashes;
569 }
570 else
571 {
572 return null;
573 }
574 }
575
576 /**
577 * Get the height
578 *
579 * @return string|null
580 */
581 public function get_height()
582 {
583 if ($this->height !== null)
584 {
585 return $this->height;
586 }
587 else
588 {
589 return null;
590 }
591 }
592
593 /**
594 * Get the language
595 *
596 * @link http://tools.ietf.org/html/rfc3066
597 * @return string|null Language code as per RFC 3066
598 */
599 public function get_language()
600 {
601 if ($this->lang !== null)
602 {
603 return $this->lang;
604 }
605 else
606 {
607 return null;
608 }
609 }
610
611 /**
612 * Get a single keyword
613 *
614 * @param int $key
615 * @return string|null
616 */
617 public function get_keyword($key = 0)
618 {
619 $keywords = $this->get_keywords();
620 if (isset($keywords[$key]))
621 {
622 return $keywords[$key];
623 }
624 else
625 {
626 return null;
627 }
628 }
629
630 /**
631 * Get all keywords
632 *
633 * @return array|null Array of strings
634 */
635 public function get_keywords()
636 {
637 if ($this->keywords !== null)
638 {
639 return $this->keywords;
640 }
641 else
642 {
643 return null;
644 }
645 }
646
647 /**
648 * Get length
649 *
650 * @return float Length in bytes
651 */
652 public function get_length()
653 {
654 if ($this->length !== null)
655 {
656 return $this->length;
657 }
658 else
659 {
660 return null;
661 }
662 }
663
664 /**
665 * Get the URL
666 *
667 * @return string|null
668 */
669 public function get_link()
670 {
671 if ($this->link !== null)
672 {
673 return urldecode($this->link);
674 }
675 else
676 {
677 return null;
678 }
679 }
680
681 /**
682 * Get the medium
683 *
684 * @link http://www.rssboard.org/media-rss#media-content
685 * @return string|null Should be one of 'image', 'audio', 'video', 'document', 'executable'
686 */
687 public function get_medium()
688 {
689 if ($this->medium !== null)
690 {
691 return $this->medium;
692 }
693 else
694 {
695 return null;
696 }
697 }
698
699 /**
700 * Get the player URL
701 *
702 * Typically the same as {@see get_permalink()}
703 * @return string|null Player URL
704 */
705 public function get_player()
706 {
707 if ($this->player !== null)
708 {
709 return $this->player;
710 }
711 else
712 {
713 return null;
714 }
715 }
716
717 /**
718 * Get a single rating
719 *
720 * @param int $key
721 * @return SimplePie_Rating|null
722 */
723 public function get_rating($key = 0)
724 {
725 $ratings = $this->get_ratings();
726 if (isset($ratings[$key]))
727 {
728 return $ratings[$key];
729 }
730 else
731 {
732 return null;
733 }
734 }
735
736 /**
737 * Get all ratings
738 *
739 * @return array|null Array of {@see SimplePie_Rating} objects
740 */
741 public function get_ratings()
742 {
743 if ($this->ratings !== null)
744 {
745 return $this->ratings;
746 }
747 else
748 {
749 return null;
750 }
751 }
752
753 /**
754 * Get a single restriction
755 *
756 * @param int $key
757 * @return SimplePie_Restriction|null
758 */
759 public function get_restriction($key = 0)
760 {
761 $restrictions = $this->get_restrictions();
762 if (isset($restrictions[$key]))
763 {
764 return $restrictions[$key];
765 }
766 else
767 {
768 return null;
769 }
770 }
771
772 /**
773 * Get all restrictions
774 *
775 * @return array|null Array of {@see SimplePie_Restriction} objects
776 */
777 public function get_restrictions()
778 {
779 if ($this->restrictions !== null)
780 {
781 return $this->restrictions;
782 }
783 else
784 {
785 return null;
786 }
787 }
788
789 /**
790 * Get the sampling rate (in kHz)
791 *
792 * @return string|null
793 */
794 public function get_sampling_rate()
795 {
796 if ($this->samplingrate !== null)
797 {
798 return $this->samplingrate;
799 }
800 else
801 {
802 return null;
803 }
804 }
805
806 /**
807 * Get the file size (in MiB)
808 *
809 * @return float|null File size in mebibytes (1048 bytes)
810 */
811 public function get_size()
812 {
813 $length = $this->get_length();
814 if ($length !== null)
815 {
816 return round($length/1048576, 2);
817 }
818 else
819 {
820 return null;
821 }
822 }
823
824 /**
825 * Get a single thumbnail
826 *
827 * @param int $key
828 * @return string|null Thumbnail URL
829 */
830 public function get_thumbnail($key = 0)
831 {
832 $thumbnails = $this->get_thumbnails();
833 if (isset($thumbnails[$key]))
834 {
835 return $thumbnails[$key];
836 }
837 else
838 {
839 return null;
840 }
841 }
842
843 /**
844 * Get all thumbnails
845 *
846 * @return array|null Array of thumbnail URLs
847 */
848 public function get_thumbnails()
849 {
850 if ($this->thumbnails !== null)
851 {
852 return $this->thumbnails;
853 }
854 else
855 {
856 return null;
857 }
858 }
859
860 /**
861 * Get the title
862 *
863 * @return string|null
864 */
865 public function get_title()
866 {
867 if ($this->title !== null)
868 {
869 return $this->title;
870 }
871 else
872 {
873 return null;
874 }
875 }
876
877 /**
878 * Get mimetype of the enclosure
879 *
880 * @see get_real_type()
881 * @return string|null MIME type
882 */
883 public function get_type()
884 {
885 if ($this->type !== null)
886 {
887 return $this->type;
888 }
889 else
890 {
891 return null;
892 }
893 }
894
895 /**
896 * Get the width
897 *
898 * @return string|null
899 */
900 public function get_width()
901 {
902 if ($this->width !== null)
903 {
904 return $this->width;
905 }
906 else
907 {
908 return null;
909 }
910 }
911
912 /**
913 * Embed the enclosure using `<embed>`
914 *
915 * @deprecated Use the second parameter to {@see embed} instead
916 *
917 * @param array|string $options See first paramter to {@see embed}
918 * @return string HTML string to output
919 */
920 public function native_embed($options='')
921 {
922 return $this->embed($options, true);
923 }
924
925 /**
926 * Embed the enclosure using Javascript
927 *
928 * `$options` is an array or comma-separated key:value string, with the
929 * following properties:
930 *
931 * - `alt` (string): Alternate content for when an end-user does not have
932 * the appropriate handler installed or when a file type is
933 * unsupported. Can be any text or HTML. Defaults to blank.
934 * - `altclass` (string): If a file type is unsupported, the end-user will
935 * see the alt text (above) linked directly to the content. That link
936 * will have this value as its class name. Defaults to blank.
937 * - `audio` (string): This is an image that should be used as a
938 * placeholder for audio files before they're loaded (QuickTime-only).
939 * Can be any relative or absolute URL. Defaults to blank.
940 * - `bgcolor` (string): The background color for the media, if not
941 * already transparent. Defaults to `#ffffff`.
942 * - `height` (integer): The height of the embedded media. Accepts any
943 * numeric pixel value (such as `360`) or `auto`. Defaults to `auto`,
944 * and it is recommended that you use this default.
945 * - `loop` (boolean): Do you want the media to loop when its done?
946 * Defaults to `false`.
947 * - `mediaplayer` (string): The location of the included
948 * `mediaplayer.swf` file. This allows for the playback of Flash Video
949 * (`.flv`) files, and is the default handler for non-Odeo MP3's.
950 * Defaults to blank.
951 * - `video` (string): This is an image that should be used as a
952 * placeholder for video files before they're loaded (QuickTime-only).
953 * Can be any relative or absolute URL. Defaults to blank.
954 * - `width` (integer): The width of the embedded media. Accepts any
955 * numeric pixel value (such as `480`) or `auto`. Defaults to `auto`,
956 * and it is recommended that you use this default.
957 * - `widescreen` (boolean): Is the enclosure widescreen or standard?
958 * This applies only to video enclosures, and will automatically resize
959 * the content appropriately. Defaults to `false`, implying 4:3 mode.
960 *
961 * Note: Non-widescreen (4:3) mode with `width` and `height` set to `auto`
962 * will default to 480x360 video resolution. Widescreen (16:9) mode with
963 * `width` and `height` set to `auto` will default to 480x270 video resolution.
964 *
965 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
966 * @param array|string $options Comma-separated key:value list, or array
967 * @param bool $native Use `<embed>`
968 * @return string HTML string to output
969 */
970 public function embed($options = '', $native = false)
971 {
972 // Set up defaults
973 $audio = '';
974 $video = '';
975 $alt = '';
976 $altclass = '';
977 $loop = 'false';
978 $width = 'auto';
979 $height = 'auto';
980 $bgcolor = '#ffffff';
981 $mediaplayer = '';
982 $widescreen = false;
983 $handler = $this->get_handler();
984 $type = $this->get_real_type();
985
986 // Process options and reassign values as necessary
987 if (is_array($options))
988 {
989 extract($options);
990 }
991 else
992 {
993 $options = explode(',', $options);
994 foreach($options as $option)
995 {
996 $opt = explode(':', $option, 2);
997 if (isset($opt[0], $opt[1]))
998 {
999 $opt[0] = trim($opt[0]);
1000 $opt[1] = trim($opt[1]);
1001 switch ($opt[0])
1002 {
1003 case 'audio':
1004 $audio = $opt[1];
1005 break;
1006
1007 case 'video':
1008 $video = $opt[1];
1009 break;
1010
1011 case 'alt':
1012 $alt = $opt[1];
1013 break;
1014
1015 case 'altclass':
1016 $altclass = $opt[1];
1017 break;
1018
1019 case 'loop':
1020 $loop = $opt[1];
1021 break;
1022
1023 case 'width':
1024 $width = $opt[1];
1025 break;
1026
1027 case 'height':
1028 $height = $opt[1];
1029 break;
1030
1031 case 'bgcolor':
1032 $bgcolor = $opt[1];
1033 break;
1034
1035 case 'mediaplayer':
1036 $mediaplayer = $opt[1];
1037 break;
1038
1039 case 'widescreen':
1040 $widescreen = $opt[1];
1041 break;
1042 }
1043 }
1044 }
1045 }
1046
1047 $mime = explode('/', $type, 2);
1048 $mime = $mime[0];
1049
1050 // Process values for 'auto'
1051 if ($width === 'auto')
1052 {
1053 if ($mime === 'video')
1054 {
1055 if ($height === 'auto')
1056 {
1057 $width = 480;
1058 }
1059 elseif ($widescreen)
1060 {
1061 $width = round((intval($height)/9)*16);
1062 }
1063 else
1064 {
1065 $width = round((intval($height)/3)*4);
1066 }
1067 }
1068 else
1069 {
1070 $width = '100%';
1071 }
1072 }
1073
1074 if ($height === 'auto')
1075 {
1076 if ($mime === 'audio')
1077 {
1078 $height = 0;
1079 }
1080 elseif ($mime === 'video')
1081 {
1082 if ($width === 'auto')
1083 {
1084 if ($widescreen)
1085 {
1086 $height = 270;
1087 }
1088 else
1089 {
1090 $height = 360;
1091 }
1092 }
1093 elseif ($widescreen)
1094 {
1095 $height = round((intval($width)/16)*9);
1096 }
1097 else
1098 {
1099 $height = round((intval($width)/4)*3);
1100 }
1101 }
1102 else
1103 {
1104 $height = 376;
1105 }
1106 }
1107 elseif ($mime === 'audio')
1108 {
1109 $height = 0;
1110 }
1111
1112 // Set proper placeholder value
1113 if ($mime === 'audio')
1114 {
1115 $placeholder = $audio;
1116 }
1117 elseif ($mime === 'video')
1118 {
1119 $placeholder = $video;
1120 }
1121
1122 $embed = '';
1123
1124 // Flash
1125 if ($handler === 'flash')
1126 {
1127 if ($native)
1128 {
1129 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
1130 }
1131 else
1132 {
1133 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
1134 }
1135 }
1136
1137 // Flash Media Player file types.
1138 // Preferred handler for MP3 file types.
1139 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
1140 {
1141 $height += 20;
1142 if ($native)
1143 {
1144 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
1145 }
1146 else
1147 {
1148 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
1149 }
1150 }
1151
1152 // QuickTime 7 file types. Need to test with QuickTime 6.
1153 // Only handle MP3's if the Flash Media Player is not present.
1154 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
1155 {
1156 $height += 16;
1157 if ($native)
1158 {
1159 if ($placeholder !== '')
1160 {
1161 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
1162 }
1163 else
1164 {
1165 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
1166 }
1167 }
1168 else
1169 {
1170 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
1171 }
1172 }
1173
1174 // Windows Media
1175 elseif ($handler === 'wmedia')
1176 {
1177 $height += 45;
1178 if ($native)
1179 {
1180 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
1181 }
1182 else
1183 {
1184 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
1185 }
1186 }
1187
1188 // Everything else
1189 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
1190
1191 return $embed;
1192 }
1193
1194 /**
1195 * Get the real media type
1196 *
1197 * Often, feeds lie to us, necessitating a bit of deeper inspection. This
1198 * converts types to their canonical representations based on the file
1199 * extension
1200 *
1201 * @see get_type()
1202 * @param bool $find_handler Internal use only, use {@see get_handler()} instead
1203 * @return string MIME type
1204 */
1205 public function get_real_type($find_handler = false)
1206 {
1207 // Mime-types by handler.
1208 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
1209 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
1210 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
1211 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
1212 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
1213
1214 if ($this->get_type() !== null)
1215 {
1216 $type = strtolower($this->type);
1217 }
1218 else
1219 {
1220 $type = null;
1221 }
1222
1223 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
1224 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
1225 {
1226 switch (strtolower($this->get_extension()))
1227 {
1228 // Audio mime-types
1229 case 'aac':
1230 case 'adts':
1231 $type = 'audio/acc';
1232 break;
1233
1234 case 'aif':
1235 case 'aifc':
1236 case 'aiff':
1237 case 'cdda':
1238 $type = 'audio/aiff';
1239 break;
1240
1241 case 'bwf':
1242 $type = 'audio/wav';
1243 break;
1244
1245 case 'kar':
1246 case 'mid':
1247 case 'midi':
1248 case 'smf':
1249 $type = 'audio/midi';
1250 break;
1251
1252 case 'm4a':
1253 $type = 'audio/x-m4a';
1254 break;
1255
1256 case 'mp3':
1257 case 'swa':
1258 $type = 'audio/mp3';
1259 break;
1260
1261 case 'wav':
1262 $type = 'audio/wav';
1263 break;
1264
1265 case 'wax':
1266 $type = 'audio/x-ms-wax';
1267 break;
1268
1269 case 'wma':
1270 $type = 'audio/x-ms-wma';
1271 break;
1272
1273 // Video mime-types
1274 case '3gp':
1275 case '3gpp':
1276 $type = 'video/3gpp';
1277 break;
1278
1279 case '3g2':
1280 case '3gp2':
1281 $type = 'video/3gpp2';
1282 break;
1283
1284 case 'asf':
1285 $type = 'video/x-ms-asf';
1286 break;
1287
1288 case 'flv':
1289 $type = 'video/x-flv';
1290 break;
1291
1292 case 'm1a':
1293 case 'm1s':
1294 case 'm1v':
1295 case 'm15':
1296 case 'm75':
1297 case 'mp2':
1298 case 'mpa':
1299 case 'mpeg':
1300 case 'mpg':
1301 case 'mpm':
1302 case 'mpv':
1303 $type = 'video/mpeg';
1304 break;
1305
1306 case 'm4v':
1307 $type = 'video/x-m4v';
1308 break;
1309
1310 case 'mov':
1311 case 'qt':
1312 $type = 'video/quicktime';
1313 break;
1314
1315 case 'mp4':
1316 case 'mpg4':
1317 $type = 'video/mp4';
1318 break;
1319
1320 case 'sdv':
1321 $type = 'video/sd-video';
1322 break;
1323
1324 case 'wm':
1325 $type = 'video/x-ms-wm';
1326 break;
1327
1328 case 'wmv':
1329 $type = 'video/x-ms-wmv';
1330 break;
1331
1332 case 'wvx':
1333 $type = 'video/x-ms-wvx';
1334 break;
1335
1336 // Flash mime-types
1337 case 'spl':
1338 $type = 'application/futuresplash';
1339 break;
1340
1341 case 'swf':
1342 $type = 'application/x-shockwave-flash';
1343 break;
1344 }
1345 }
1346
1347 if ($find_handler)
1348 {
1349 if (in_array($type, $types_flash))
1350 {
1351 return 'flash';
1352 }
1353 elseif (in_array($type, $types_fmedia))
1354 {
1355 return 'fmedia';
1356 }
1357 elseif (in_array($type, $types_quicktime))
1358 {
1359 return 'quicktime';
1360 }
1361 elseif (in_array($type, $types_wmedia))
1362 {
1363 return 'wmedia';
1364 }
1365 elseif (in_array($type, $types_mp3))
1366 {
1367 return 'mp3';
1368 }
1369 else
1370 {
1371 return null;
1372 }
1373 }
1374 else
1375 {
1376 return $type;
1377 }
1378 }
1379}
1380
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Exception.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Exception.php
new file mode 100644
index 00000000..73e104d6
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Exception.php
@@ -0,0 +1,52 @@
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.4-dev
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 * General SimplePie exception class
47 *
48 * @package SimplePie
49 */
50class SimplePie_Exception extends Exception
51{
52} \ No newline at end of file
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/File.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/File.php
new file mode 100644
index 00000000..b7d1a2ac
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/File.php
@@ -0,0 +1,292 @@
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 fetching remote files and reading local files
47 *
48 * Supports HTTP 1.0 via cURL or fsockopen, with spotty HTTP 1.1 support
49 *
50 * This class can be overloaded with {@see SimplePie::set_file_class()}
51 *
52 * @package SimplePie
53 * @subpackage HTTP
54 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
55 */
56class SimplePie_File
57{
58 var $url;
59 var $useragent;
60 var $success = true;
61 var $headers = array();
62 var $body;
63 var $status_code;
64 var $redirects = 0;
65 var $error;
66 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
67
68 public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
69 {
70 if (class_exists('idna_convert'))
71 {
72 $idn = new idna_convert();
73 $parsed = SimplePie_Misc::parse_url($url);
74 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
75 }
76 $this->url = $url;
77 $this->useragent = $useragent;
78 if (preg_match('/^http(s)?:\/\//i', $url))
79 {
80 if ($useragent === null)
81 {
82 $useragent = ini_get('user_agent');
83 $this->useragent = $useragent;
84 }
85 if (!is_array($headers))
86 {
87 $headers = array();
88 }
89 if (!$force_fsockopen && function_exists('curl_exec'))
90 {
91 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
92 $fp = curl_init();
93 $headers2 = array();
94 foreach ($headers as $key => $value)
95 {
96 $headers2[] = "$key: $value";
97 }
98 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
99 {
100 curl_setopt($fp, CURLOPT_ENCODING, '');
101 }
102 curl_setopt($fp, CURLOPT_URL, $url);
103 curl_setopt($fp, CURLOPT_HEADER, 1);
104 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
105 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
106 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
107 curl_setopt($fp, CURLOPT_REFERER, $url);
108 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
109 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
110 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
111 {
112 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
113 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
114 }
115
116 $this->headers = curl_exec($fp);
117 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
118 {
119 curl_setopt($fp, CURLOPT_ENCODING, 'none');
120 $this->headers = curl_exec($fp);
121 }
122 if (curl_errno($fp))
123 {
124 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
125 $this->success = false;
126 }
127 else
128 {
129 $info = curl_getinfo($fp);
130 curl_close($fp);
131 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
132 $this->headers = array_pop($this->headers);
133 $parser = new SimplePie_HTTP_Parser($this->headers);
134 if ($parser->parse())
135 {
136 $this->headers = $parser->headers;
137 $this->body = $parser->body;
138 $this->status_code = $parser->status_code;
139 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
140 {
141 $this->redirects++;
142 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
143 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
144 }
145 }
146 }
147 }
148 else
149 {
150 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
151 $url_parts = parse_url($url);
152 $socket_host = $url_parts['host'];
153 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
154 {
155 $socket_host = "ssl://$url_parts[host]";
156 $url_parts['port'] = 443;
157 }
158 if (!isset($url_parts['port']))
159 {
160 $url_parts['port'] = 80;
161 }
162 $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
163 if (!$fp)
164 {
165 $this->error = 'fsockopen error: ' . $errstr;
166 $this->success = false;
167 }
168 else
169 {
170 stream_set_timeout($fp, $timeout);
171 if (isset($url_parts['path']))
172 {
173 if (isset($url_parts['query']))
174 {
175 $get = "$url_parts[path]?$url_parts[query]";
176 }
177 else
178 {
179 $get = $url_parts['path'];
180 }
181 }
182 else
183 {
184 $get = '/';
185 }
186 $out = "GET $get HTTP/1.1\r\n";
187 $out .= "Host: $url_parts[host]\r\n";
188 $out .= "User-Agent: $useragent\r\n";
189 if (extension_loaded('zlib'))
190 {
191 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
192 }
193
194 if (isset($url_parts['user']) && isset($url_parts['pass']))
195 {
196 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
197 }
198 foreach ($headers as $key => $value)
199 {
200 $out .= "$key: $value\r\n";
201 }
202 $out .= "Connection: Close\r\n\r\n";
203 fwrite($fp, $out);
204
205 $info = stream_get_meta_data($fp);
206
207 $this->headers = '';
208 while (!$info['eof'] && !$info['timed_out'])
209 {
210 $this->headers .= fread($fp, 1160);
211 $info = stream_get_meta_data($fp);
212 }
213 if (!$info['timed_out'])
214 {
215 $parser = new SimplePie_HTTP_Parser($this->headers);
216 if ($parser->parse())
217 {
218 $this->headers = $parser->headers;
219 $this->body = $parser->body;
220 $this->status_code = $parser->status_code;
221 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
222 {
223 $this->redirects++;
224 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
225 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
226 }
227 if (isset($this->headers['content-encoding']))
228 {
229 // Hey, we act dumb elsewhere, so let's do that here too
230 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
231 {
232 case 'gzip':
233 case 'x-gzip':
234 $decoder = new SimplePie_gzdecode($this->body);
235 if (!$decoder->parse())
236 {
237 $this->error = 'Unable to decode HTTP "gzip" stream';
238 $this->success = false;
239 }
240 else
241 {
242 $this->body = $decoder->data;
243 }
244 break;
245
246 case 'deflate':
247 if (($decompressed = gzinflate($this->body)) !== false)
248 {
249 $this->body = $decompressed;
250 }
251 else if (($decompressed = gzuncompress($this->body)) !== false)
252 {
253 $this->body = $decompressed;
254 }
255 else if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false)
256 {
257 $this->body = $decompressed;
258 }
259 else
260 {
261 $this->error = 'Unable to decode HTTP "deflate" stream';
262 $this->success = false;
263 }
264 break;
265
266 default:
267 $this->error = 'Unknown content coding';
268 $this->success = false;
269 }
270 }
271 }
272 }
273 else
274 {
275 $this->error = 'fsocket timed out';
276 $this->success = false;
277 }
278 fclose($fp);
279 }
280 }
281 }
282 else
283 {
284 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
285 if (!$this->body = file_get_contents($url))
286 {
287 $this->error = 'file_get_contents could not read the file';
288 $this->success = false;
289 }
290 }
291 }
292}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/HTTP/Parser.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/HTTP/Parser.php
new file mode 100644
index 00000000..bff2222b
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/HTTP/Parser.php
@@ -0,0 +1,500 @@
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/**
47 * HTTP Response Parser
48 *
49 * @package SimplePie
50 * @subpackage HTTP
51 */
52class SimplePie_HTTP_Parser
53{
54 /**
55 * HTTP Version
56 *
57 * @var float
58 */
59 public $http_version = 0.0;
60
61 /**
62 * Status code
63 *
64 * @var int
65 */
66 public $status_code = 0;
67
68 /**
69 * Reason phrase
70 *
71 * @var string
72 */
73 public $reason = '';
74
75 /**
76 * Key/value pairs of the headers
77 *
78 * @var array
79 */
80 public $headers = array();
81
82 /**
83 * Body of the response
84 *
85 * @var string
86 */
87 public $body = '';
88
89 /**
90 * Current state of the state machine
91 *
92 * @var string
93 */
94 protected $state = 'http_version';
95
96 /**
97 * Input data
98 *
99 * @var string
100 */
101 protected $data = '';
102
103 /**
104 * Input data length (to avoid calling strlen() everytime this is needed)
105 *
106 * @var int
107 */
108 protected $data_length = 0;
109
110 /**
111 * Current position of the pointer
112 *
113 * @var int
114 */
115 protected $position = 0;
116
117 /**
118 * Name of the hedaer currently being parsed
119 *
120 * @var string
121 */
122 protected $name = '';
123
124 /**
125 * Value of the hedaer currently being parsed
126 *
127 * @var string
128 */
129 protected $value = '';
130
131 /**
132 * Create an instance of the class with the input data
133 *
134 * @param string $data Input data
135 */
136 public function __construct($data)
137 {
138 $this->data = $data;
139 $this->data_length = strlen($this->data);
140 }
141
142 /**
143 * Parse the input data
144 *
145 * @return bool true on success, false on failure
146 */
147 public function parse()
148 {
149 while ($this->state && $this->state !== 'emit' && $this->has_data())
150 {
151 $state = $this->state;
152 $this->$state();
153 }
154 $this->data = '';
155 if ($this->state === 'emit' || $this->state === 'body')
156 {
157 return true;
158 }
159 else
160 {
161 $this->http_version = '';
162 $this->status_code = '';
163 $this->reason = '';
164 $this->headers = array();
165 $this->body = '';
166 return false;
167 }
168 }
169
170 /**
171 * Check whether there is data beyond the pointer
172 *
173 * @return bool true if there is further data, false if not
174 */
175 protected function has_data()
176 {
177 return (bool) ($this->position < $this->data_length);
178 }
179
180 /**
181 * See if the next character is LWS
182 *
183 * @return bool true if the next character is LWS, false if not
184 */
185 protected function is_linear_whitespace()
186 {
187 return (bool) ($this->data[$this->position] === "\x09"
188 || $this->data[$this->position] === "\x20"
189 || ($this->data[$this->position] === "\x0A"
190 && isset($this->data[$this->position + 1])
191 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
192 }
193
194 /**
195 * Parse the HTTP version
196 */
197 protected function http_version()
198 {
199 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
200 {
201 $len = strspn($this->data, '0123456789.', 5);
202 $this->http_version = substr($this->data, 5, $len);
203 $this->position += 5 + $len;
204 if (substr_count($this->http_version, '.') <= 1)
205 {
206 $this->http_version = (float) $this->http_version;
207 $this->position += strspn($this->data, "\x09\x20", $this->position);
208 $this->state = 'status';
209 }
210 else
211 {
212 $this->state = false;
213 }
214 }
215 else
216 {
217 $this->state = false;
218 }
219 }
220
221 /**
222 * Parse the status code
223 */
224 protected function status()
225 {
226 if ($len = strspn($this->data, '0123456789', $this->position))
227 {
228 $this->status_code = (int) substr($this->data, $this->position, $len);
229 $this->position += $len;
230 $this->state = 'reason';
231 }
232 else
233 {
234 $this->state = false;
235 }
236 }
237
238 /**
239 * Parse the reason phrase
240 */
241 protected function reason()
242 {
243 $len = strcspn($this->data, "\x0A", $this->position);
244 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
245 $this->position += $len + 1;
246 $this->state = 'new_line';
247 }
248
249 /**
250 * Deal with a new line, shifting data around as needed
251 */
252 protected function new_line()
253 {
254 $this->value = trim($this->value, "\x0D\x20");
255 if ($this->name !== '' && $this->value !== '')
256 {
257 $this->name = strtolower($this->name);
258 // We should only use the last Content-Type header. c.f. issue #1
259 if (isset($this->headers[$this->name]) && $this->name !== 'content-type')
260 {
261 $this->headers[$this->name] .= ', ' . $this->value;
262 }
263 else
264 {
265 $this->headers[$this->name] = $this->value;
266 }
267 }
268 $this->name = '';
269 $this->value = '';
270 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
271 {
272 $this->position += 2;
273 $this->state = 'body';
274 }
275 elseif ($this->data[$this->position] === "\x0A")
276 {
277 $this->position++;
278 $this->state = 'body';
279 }
280 else
281 {
282 $this->state = 'name';
283 }
284 }
285
286 /**
287 * Parse a header name
288 */
289 protected function name()
290 {
291 $len = strcspn($this->data, "\x0A:", $this->position);
292 if (isset($this->data[$this->position + $len]))
293 {
294 if ($this->data[$this->position + $len] === "\x0A")
295 {
296 $this->position += $len;
297 $this->state = 'new_line';
298 }
299 else
300 {
301 $this->name = substr($this->data, $this->position, $len);
302 $this->position += $len + 1;
303 $this->state = 'value';
304 }
305 }
306 else
307 {
308 $this->state = false;
309 }
310 }
311
312 /**
313 * Parse LWS, replacing consecutive LWS characters with a single space
314 */
315 protected function linear_whitespace()
316 {
317 do
318 {
319 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
320 {
321 $this->position += 2;
322 }
323 elseif ($this->data[$this->position] === "\x0A")
324 {
325 $this->position++;
326 }
327 $this->position += strspn($this->data, "\x09\x20", $this->position);
328 } while ($this->has_data() && $this->is_linear_whitespace());
329 $this->value .= "\x20";
330 }
331
332 /**
333 * See what state to move to while within non-quoted header values
334 */
335 protected function value()
336 {
337 if ($this->is_linear_whitespace())
338 {
339 $this->linear_whitespace();
340 }
341 else
342 {
343 switch ($this->data[$this->position])
344 {
345 case '"':
346 // Workaround for ETags: we have to include the quotes as
347 // part of the tag.
348 if (strtolower($this->name) === 'etag')
349 {
350 $this->value .= '"';
351 $this->position++;
352 $this->state = 'value_char';
353 break;
354 }
355 $this->position++;
356 $this->state = 'quote';
357 break;
358
359 case "\x0A":
360 $this->position++;
361 $this->state = 'new_line';
362 break;
363
364 default:
365 $this->state = 'value_char';
366 break;
367 }
368 }
369 }
370
371 /**
372 * Parse a header value while outside quotes
373 */
374 protected function value_char()
375 {
376 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
377 $this->value .= substr($this->data, $this->position, $len);
378 $this->position += $len;
379 $this->state = 'value';
380 }
381
382 /**
383 * See what state to move to while within quoted header values
384 */
385 protected function quote()
386 {
387 if ($this->is_linear_whitespace())
388 {
389 $this->linear_whitespace();
390 }
391 else
392 {
393 switch ($this->data[$this->position])
394 {
395 case '"':
396 $this->position++;
397 $this->state = 'value';
398 break;
399
400 case "\x0A":
401 $this->position++;
402 $this->state = 'new_line';
403 break;
404
405 case '\\':
406 $this->position++;
407 $this->state = 'quote_escaped';
408 break;
409
410 default:
411 $this->state = 'quote_char';
412 break;
413 }
414 }
415 }
416
417 /**
418 * Parse a header value while within quotes
419 */
420 protected function quote_char()
421 {
422 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
423 $this->value .= substr($this->data, $this->position, $len);
424 $this->position += $len;
425 $this->state = 'value';
426 }
427
428 /**
429 * Parse an escaped character within quotes
430 */
431 protected function quote_escaped()
432 {
433 $this->value .= $this->data[$this->position];
434 $this->position++;
435 $this->state = 'quote';
436 }
437
438 /**
439 * Parse the body
440 */
441 protected function body()
442 {
443 $this->body = substr($this->data, $this->position);
444 if (!empty($this->headers['transfer-encoding']))
445 {
446 unset($this->headers['transfer-encoding']);
447 $this->state = 'chunked';
448 }
449 else
450 {
451 $this->state = 'emit';
452 }
453 }
454
455 /**
456 * Parsed a "Transfer-Encoding: chunked" body
457 */
458 protected function chunked()
459 {
460 if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($this->body)))
461 {
462 $this->state = 'emit';
463 return;
464 }
465
466 $decoded = '';
467 $encoded = $this->body;
468
469 while (true)
470 {
471 $is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
472 if (!$is_chunked)
473 {
474 // Looks like it's not chunked after all
475 $this->state = 'emit';
476 return;
477 }
478
479 $length = hexdec(trim($matches[1]));
480 if ($length === 0)
481 {
482 // Ignore trailer headers
483 $this->state = 'emit';
484 $this->body = $decoded;
485 return;
486 }
487
488 $chunk_length = strlen($matches[0]);
489 $decoded .= $part = substr($encoded, $chunk_length, $length);
490 $encoded = substr($encoded, $chunk_length + $length + 2);
491
492 if (trim($encoded) === '0' || empty($encoded))
493 {
494 $this->state = 'emit';
495 $this->body = $decoded;
496 return;
497 }
498 }
499 }
500}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/IRI.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/IRI.php
new file mode 100644
index 00000000..d3198c04
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/IRI.php
@@ -0,0 +1,1238 @@
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 * IRI parser/serialiser/normaliser
47 *
48 * @package SimplePie
49 * @subpackage HTTP
50 * @author Geoffrey Sneddon
51 * @author Steve Minutillo
52 * @author Ryan McCue
53 * @copyright 2007-2012 Geoffrey Sneddon, Steve Minutillo, Ryan McCue
54 * @license http://www.opensource.org/licenses/bsd-license.php
55 */
56class SimplePie_IRI
57{
58 /**
59 * Scheme
60 *
61 * @var string
62 */
63 protected $scheme = null;
64
65 /**
66 * User Information
67 *
68 * @var string
69 */
70 protected $iuserinfo = null;
71
72 /**
73 * ihost
74 *
75 * @var string
76 */
77 protected $ihost = null;
78
79 /**
80 * Port
81 *
82 * @var string
83 */
84 protected $port = null;
85
86 /**
87 * ipath
88 *
89 * @var string
90 */
91 protected $ipath = '';
92
93 /**
94 * iquery
95 *
96 * @var string
97 */
98 protected $iquery = null;
99
100 /**
101 * ifragment
102 *
103 * @var string
104 */
105 protected $ifragment = null;
106
107 /**
108 * Normalization database
109 *
110 * Each key is the scheme, each value is an array with each key as the IRI
111 * part and value as the default value for that part.
112 */
113 protected $normalization = array(
114 'acap' => array(
115 'port' => 674
116 ),
117 'dict' => array(
118 'port' => 2628
119 ),
120 'file' => array(
121 'ihost' => 'localhost'
122 ),
123 'http' => array(
124 'port' => 80,
125 'ipath' => '/'
126 ),
127 'https' => array(
128 'port' => 443,
129 'ipath' => '/'
130 ),
131 );
132
133 /**
134 * Return the entire IRI when you try and read the object as a string
135 *
136 * @return string
137 */
138 public function __toString()
139 {
140 return $this->get_iri();
141 }
142
143 /**
144 * Overload __set() to provide access via properties
145 *
146 * @param string $name Property name
147 * @param mixed $value Property value
148 */
149 public function __set($name, $value)
150 {
151 if (method_exists($this, 'set_' . $name))
152 {
153 call_user_func(array($this, 'set_' . $name), $value);
154 }
155 elseif (
156 $name === 'iauthority'
157 || $name === 'iuserinfo'
158 || $name === 'ihost'
159 || $name === 'ipath'
160 || $name === 'iquery'
161 || $name === 'ifragment'
162 )
163 {
164 call_user_func(array($this, 'set_' . substr($name, 1)), $value);
165 }
166 }
167
168 /**
169 * Overload __get() to provide access via properties
170 *
171 * @param string $name Property name
172 * @return mixed
173 */
174 public function __get($name)
175 {
176 // isset() returns false for null, we don't want to do that
177 // Also why we use array_key_exists below instead of isset()
178 $props = get_object_vars($this);
179
180 if (
181 $name === 'iri' ||
182 $name === 'uri' ||
183 $name === 'iauthority' ||
184 $name === 'authority'
185 )
186 {
187 $return = $this->{"get_$name"}();
188 }
189 elseif (array_key_exists($name, $props))
190 {
191 $return = $this->$name;
192 }
193 // host -> ihost
194 elseif (($prop = 'i' . $name) && array_key_exists($prop, $props))
195 {
196 $name = $prop;
197 $return = $this->$prop;
198 }
199 // ischeme -> scheme
200 elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props))
201 {
202 $name = $prop;
203 $return = $this->$prop;
204 }
205 else
206 {
207 trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
208 $return = null;
209 }
210
211 if ($return === null && isset($this->normalization[$this->scheme][$name]))
212 {
213 return $this->normalization[$this->scheme][$name];
214 }
215 else
216 {
217 return $return;
218 }
219 }
220
221 /**
222 * Overload __isset() to provide access via properties
223 *
224 * @param string $name Property name
225 * @return bool
226 */
227 public function __isset($name)
228 {
229 if (method_exists($this, 'get_' . $name) || isset($this->$name))
230 {
231 return true;
232 }
233 else
234 {
235 return false;
236 }
237 }
238
239 /**
240 * Overload __unset() to provide access via properties
241 *
242 * @param string $name Property name
243 */
244 public function __unset($name)
245 {
246 if (method_exists($this, 'set_' . $name))
247 {
248 call_user_func(array($this, 'set_' . $name), '');
249 }
250 }
251
252 /**
253 * Create a new IRI object, from a specified string
254 *
255 * @param string $iri
256 */
257 public function __construct($iri = null)
258 {
259 $this->set_iri($iri);
260 }
261
262 /**
263 * Create a new IRI object by resolving a relative IRI
264 *
265 * Returns false if $base is not absolute, otherwise an IRI.
266 *
267 * @param IRI|string $base (Absolute) Base IRI
268 * @param IRI|string $relative Relative IRI
269 * @return IRI|false
270 */
271 public static function absolutize($base, $relative)
272 {
273 if (!($relative instanceof SimplePie_IRI))
274 {
275 $relative = new SimplePie_IRI($relative);
276 }
277 if (!$relative->is_valid())
278 {
279 return false;
280 }
281 elseif ($relative->scheme !== null)
282 {
283 return clone $relative;
284 }
285 else
286 {
287 if (!($base instanceof SimplePie_IRI))
288 {
289 $base = new SimplePie_IRI($base);
290 }
291 if ($base->scheme !== null && $base->is_valid())
292 {
293 if ($relative->get_iri() !== '')
294 {
295 if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null)
296 {
297 $target = clone $relative;
298 $target->scheme = $base->scheme;
299 }
300 else
301 {
302 $target = new SimplePie_IRI;
303 $target->scheme = $base->scheme;
304 $target->iuserinfo = $base->iuserinfo;
305 $target->ihost = $base->ihost;
306 $target->port = $base->port;
307 if ($relative->ipath !== '')
308 {
309 if ($relative->ipath[0] === '/')
310 {
311 $target->ipath = $relative->ipath;
312 }
313 elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '')
314 {
315 $target->ipath = '/' . $relative->ipath;
316 }
317 elseif (($last_segment = strrpos($base->ipath, '/')) !== false)
318 {
319 $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
320 }
321 else
322 {
323 $target->ipath = $relative->ipath;
324 }
325 $target->ipath = $target->remove_dot_segments($target->ipath);
326 $target->iquery = $relative->iquery;
327 }
328 else
329 {
330 $target->ipath = $base->ipath;
331 if ($relative->iquery !== null)
332 {
333 $target->iquery = $relative->iquery;
334 }
335 elseif ($base->iquery !== null)
336 {
337 $target->iquery = $base->iquery;
338 }
339 }
340 $target->ifragment = $relative->ifragment;
341 }
342 }
343 else
344 {
345 $target = clone $base;
346 $target->ifragment = null;
347 }
348 $target->scheme_normalization();
349 return $target;
350 }
351 else
352 {
353 return false;
354 }
355 }
356 }
357
358 /**
359 * Parse an IRI into scheme/authority/path/query/fragment segments
360 *
361 * @param string $iri
362 * @return array
363 */
364 protected function parse_iri($iri)
365 {
366 $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
367 if (preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match))
368 {
369 if ($match[1] === '')
370 {
371 $match['scheme'] = null;
372 }
373 if (!isset($match[3]) || $match[3] === '')
374 {
375 $match['authority'] = null;
376 }
377 if (!isset($match[5]))
378 {
379 $match['path'] = '';
380 }
381 if (!isset($match[6]) || $match[6] === '')
382 {
383 $match['query'] = null;
384 }
385 if (!isset($match[8]) || $match[8] === '')
386 {
387 $match['fragment'] = null;
388 }
389 return $match;
390 }
391 else
392 {
393 // This can occur when a paragraph is accidentally parsed as a URI
394 return false;
395 }
396 }
397
398 /**
399 * Remove dot segments from a path
400 *
401 * @param string $input
402 * @return string
403 */
404 protected function remove_dot_segments($input)
405 {
406 $output = '';
407 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
408 {
409 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
410 if (strpos($input, '../') === 0)
411 {
412 $input = substr($input, 3);
413 }
414 elseif (strpos($input, './') === 0)
415 {
416 $input = substr($input, 2);
417 }
418 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
419 elseif (strpos($input, '/./') === 0)
420 {
421 $input = substr($input, 2);
422 }
423 elseif ($input === '/.')
424 {
425 $input = '/';
426 }
427 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
428 elseif (strpos($input, '/../') === 0)
429 {
430 $input = substr($input, 3);
431 $output = substr_replace($output, '', strrpos($output, '/'));
432 }
433 elseif ($input === '/..')
434 {
435 $input = '/';
436 $output = substr_replace($output, '', strrpos($output, '/'));
437 }
438 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
439 elseif ($input === '.' || $input === '..')
440 {
441 $input = '';
442 }
443 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
444 elseif (($pos = strpos($input, '/', 1)) !== false)
445 {
446 $output .= substr($input, 0, $pos);
447 $input = substr_replace($input, '', 0, $pos);
448 }
449 else
450 {
451 $output .= $input;
452 $input = '';
453 }
454 }
455 return $output . $input;
456 }
457
458 /**
459 * Replace invalid character with percent encoding
460 *
461 * @param string $string Input string
462 * @param string $extra_chars Valid characters not in iunreserved or
463 * iprivate (this is ASCII-only)
464 * @param bool $iprivate Allow iprivate
465 * @return string
466 */
467 protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false)
468 {
469 // Normalize as many pct-encoded sections as possible
470 $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $string);
471
472 // Replace invalid percent characters
473 $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
474
475 // Add unreserved and % to $extra_chars (the latter is safe because all
476 // pct-encoded sections are now valid).
477 $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
478
479 // Now replace any bytes that aren't allowed with their pct-encoded versions
480 $position = 0;
481 $strlen = strlen($string);
482 while (($position += strspn($string, $extra_chars, $position)) < $strlen)
483 {
484 $value = ord($string[$position]);
485
486 // Start position
487 $start = $position;
488
489 // By default we are valid
490 $valid = true;
491
492 // No one byte sequences are valid due to the while.
493 // Two byte sequence:
494 if (($value & 0xE0) === 0xC0)
495 {
496 $character = ($value & 0x1F) << 6;
497 $length = 2;
498 $remaining = 1;
499 }
500 // Three byte sequence:
501 elseif (($value & 0xF0) === 0xE0)
502 {
503 $character = ($value & 0x0F) << 12;
504 $length = 3;
505 $remaining = 2;
506 }
507 // Four byte sequence:
508 elseif (($value & 0xF8) === 0xF0)
509 {
510 $character = ($value & 0x07) << 18;
511 $length = 4;
512 $remaining = 3;
513 }
514 // Invalid byte:
515 else
516 {
517 $valid = false;
518 $length = 1;
519 $remaining = 0;
520 }
521
522 if ($remaining)
523 {
524 if ($position + $length <= $strlen)
525 {
526 for ($position++; $remaining; $position++)
527 {
528 $value = ord($string[$position]);
529
530 // Check that the byte is valid, then add it to the character:
531 if (($value & 0xC0) === 0x80)
532 {
533 $character |= ($value & 0x3F) << (--$remaining * 6);
534 }
535 // If it is invalid, count the sequence as invalid and reprocess the current byte:
536 else
537 {
538 $valid = false;
539 $position--;
540 break;
541 }
542 }
543 }
544 else
545 {
546 $position = $strlen - 1;
547 $valid = false;
548 }
549 }
550
551 // Percent encode anything invalid or not in ucschar
552 if (
553 // Invalid sequences
554 !$valid
555 // Non-shortest form sequences are invalid
556 || $length > 1 && $character <= 0x7F
557 || $length > 2 && $character <= 0x7FF
558 || $length > 3 && $character <= 0xFFFF
559 // Outside of range of ucschar codepoints
560 // Noncharacters
561 || ($character & 0xFFFE) === 0xFFFE
562 || $character >= 0xFDD0 && $character <= 0xFDEF
563 || (
564 // Everything else not in ucschar
565 $character > 0xD7FF && $character < 0xF900
566 || $character < 0xA0
567 || $character > 0xEFFFD
568 )
569 && (
570 // Everything not in iprivate, if it applies
571 !$iprivate
572 || $character < 0xE000
573 || $character > 0x10FFFD
574 )
575 )
576 {
577 // If we were a character, pretend we weren't, but rather an error.
578 if ($valid)
579 $position--;
580
581 for ($j = $start; $j <= $position; $j++)
582 {
583 $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
584 $j += 2;
585 $position += 2;
586 $strlen += 2;
587 }
588 }
589 }
590
591 return $string;
592 }
593
594 /**
595 * Callback function for preg_replace_callback.
596 *
597 * Removes sequences of percent encoded bytes that represent UTF-8
598 * encoded characters in iunreserved
599 *
600 * @param array $match PCRE match
601 * @return string Replacement
602 */
603 protected function remove_iunreserved_percent_encoded($match)
604 {
605 // As we just have valid percent encoded sequences we can just explode
606 // and ignore the first member of the returned array (an empty string).
607 $bytes = explode('%', $match[0]);
608
609 // Initialize the new string (this is what will be returned) and that
610 // there are no bytes remaining in the current sequence (unsurprising
611 // at the first byte!).
612 $string = '';
613 $remaining = 0;
614
615 // Loop over each and every byte, and set $value to its value
616 for ($i = 1, $len = count($bytes); $i < $len; $i++)
617 {
618 $value = hexdec($bytes[$i]);
619
620 // If we're the first byte of sequence:
621 if (!$remaining)
622 {
623 // Start position
624 $start = $i;
625
626 // By default we are valid
627 $valid = true;
628
629 // One byte sequence:
630 if ($value <= 0x7F)
631 {
632 $character = $value;
633 $length = 1;
634 }
635 // Two byte sequence:
636 elseif (($value & 0xE0) === 0xC0)
637 {
638 $character = ($value & 0x1F) << 6;
639 $length = 2;
640 $remaining = 1;
641 }
642 // Three byte sequence:
643 elseif (($value & 0xF0) === 0xE0)
644 {
645 $character = ($value & 0x0F) << 12;
646 $length = 3;
647 $remaining = 2;
648 }
649 // Four byte sequence:
650 elseif (($value & 0xF8) === 0xF0)
651 {
652 $character = ($value & 0x07) << 18;
653 $length = 4;
654 $remaining = 3;
655 }
656 // Invalid byte:
657 else
658 {
659 $valid = false;
660 $remaining = 0;
661 }
662 }
663 // Continuation byte:
664 else
665 {
666 // Check that the byte is valid, then add it to the character:
667 if (($value & 0xC0) === 0x80)
668 {
669 $remaining--;
670 $character |= ($value & 0x3F) << ($remaining * 6);
671 }
672 // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
673 else
674 {
675 $valid = false;
676 $remaining = 0;
677 $i--;
678 }
679 }
680
681 // If we've reached the end of the current byte sequence, append it to Unicode::$data
682 if (!$remaining)
683 {
684 // Percent encode anything invalid or not in iunreserved
685 if (
686 // Invalid sequences
687 !$valid
688 // Non-shortest form sequences are invalid
689 || $length > 1 && $character <= 0x7F
690 || $length > 2 && $character <= 0x7FF
691 || $length > 3 && $character <= 0xFFFF
692 // Outside of range of iunreserved codepoints
693 || $character < 0x2D
694 || $character > 0xEFFFD
695 // Noncharacters
696 || ($character & 0xFFFE) === 0xFFFE
697 || $character >= 0xFDD0 && $character <= 0xFDEF
698 // Everything else not in iunreserved (this is all BMP)
699 || $character === 0x2F
700 || $character > 0x39 && $character < 0x41
701 || $character > 0x5A && $character < 0x61
702 || $character > 0x7A && $character < 0x7E
703 || $character > 0x7E && $character < 0xA0
704 || $character > 0xD7FF && $character < 0xF900
705 )
706 {
707 for ($j = $start; $j <= $i; $j++)
708 {
709 $string .= '%' . strtoupper($bytes[$j]);
710 }
711 }
712 else
713 {
714 for ($j = $start; $j <= $i; $j++)
715 {
716 $string .= chr(hexdec($bytes[$j]));
717 }
718 }
719 }
720 }
721
722 // If we have any bytes left over they are invalid (i.e., we are
723 // mid-way through a multi-byte sequence)
724 if ($remaining)
725 {
726 for ($j = $start; $j < $len; $j++)
727 {
728 $string .= '%' . strtoupper($bytes[$j]);
729 }
730 }
731
732 return $string;
733 }
734
735 protected function scheme_normalization()
736 {
737 if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo'])
738 {
739 $this->iuserinfo = null;
740 }
741 if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost'])
742 {
743 $this->ihost = null;
744 }
745 if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port'])
746 {
747 $this->port = null;
748 }
749 if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath'])
750 {
751 $this->ipath = '';
752 }
753 if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery'])
754 {
755 $this->iquery = null;
756 }
757 if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment'])
758 {
759 $this->ifragment = null;
760 }
761 }
762
763 /**
764 * Check if the object represents a valid IRI. This needs to be done on each
765 * call as some things change depending on another part of the IRI.
766 *
767 * @return bool
768 */
769 public function is_valid()
770 {
771 $isauthority = $this->iuserinfo !== null || $this->ihost !== null || $this->port !== null;
772 if ($this->ipath !== '' &&
773 (
774 $isauthority && (
775 $this->ipath[0] !== '/' ||
776 substr($this->ipath, 0, 2) === '//'
777 ) ||
778 (
779 $this->scheme === null &&
780 !$isauthority &&
781 strpos($this->ipath, ':') !== false &&
782 (strpos($this->ipath, '/') === false ? true : strpos($this->ipath, ':') < strpos($this->ipath, '/'))
783 )
784 )
785 )
786 {
787 return false;
788 }
789
790 return true;
791 }
792
793 /**
794 * Set the entire IRI. Returns true on success, false on failure (if there
795 * are any invalid characters).
796 *
797 * @param string $iri
798 * @return bool
799 */
800 public function set_iri($iri)
801 {
802 static $cache;
803 if (!$cache)
804 {
805 $cache = array();
806 }
807
808 if ($iri === null)
809 {
810 return true;
811 }
812 elseif (isset($cache[$iri]))
813 {
814 list($this->scheme,
815 $this->iuserinfo,
816 $this->ihost,
817 $this->port,
818 $this->ipath,
819 $this->iquery,
820 $this->ifragment,
821 $return) = $cache[$iri];
822 return $return;
823 }
824 else
825 {
826 $parsed = $this->parse_iri((string) $iri);
827 if (!$parsed)
828 {
829 return false;
830 }
831
832 $return = $this->set_scheme($parsed['scheme'])
833 && $this->set_authority($parsed['authority'])
834 && $this->set_path($parsed['path'])
835 && $this->set_query($parsed['query'])
836 && $this->set_fragment($parsed['fragment']);
837
838 $cache[$iri] = array($this->scheme,
839 $this->iuserinfo,
840 $this->ihost,
841 $this->port,
842 $this->ipath,
843 $this->iquery,
844 $this->ifragment,
845 $return);
846 return $return;
847 }
848 }
849
850 /**
851 * Set the scheme. Returns true on success, false on failure (if there are
852 * any invalid characters).
853 *
854 * @param string $scheme
855 * @return bool
856 */
857 public function set_scheme($scheme)
858 {
859 if ($scheme === null)
860 {
861 $this->scheme = null;
862 }
863 elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme))
864 {
865 $this->scheme = null;
866 return false;
867 }
868 else
869 {
870 $this->scheme = strtolower($scheme);
871 }
872 return true;
873 }
874
875 /**
876 * Set the authority. Returns true on success, false on failure (if there are
877 * any invalid characters).
878 *
879 * @param string $authority
880 * @return bool
881 */
882 public function set_authority($authority)
883 {
884 static $cache;
885 if (!$cache)
886 $cache = array();
887
888 if ($authority === null)
889 {
890 $this->iuserinfo = null;
891 $this->ihost = null;
892 $this->port = null;
893 return true;
894 }
895 elseif (isset($cache[$authority]))
896 {
897 list($this->iuserinfo,
898 $this->ihost,
899 $this->port,
900 $return) = $cache[$authority];
901
902 return $return;
903 }
904 else
905 {
906 $remaining = $authority;
907 if (($iuserinfo_end = strrpos($remaining, '@')) !== false)
908 {
909 $iuserinfo = substr($remaining, 0, $iuserinfo_end);
910 $remaining = substr($remaining, $iuserinfo_end + 1);
911 }
912 else
913 {
914 $iuserinfo = null;
915 }
916 if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false)
917 {
918 if (($port = substr($remaining, $port_start + 1)) === false)
919 {
920 $port = null;
921 }
922 $remaining = substr($remaining, 0, $port_start);
923 }
924 else
925 {
926 $port = null;
927 }
928
929 $return = $this->set_userinfo($iuserinfo) &&
930 $this->set_host($remaining) &&
931 $this->set_port($port);
932
933 $cache[$authority] = array($this->iuserinfo,
934 $this->ihost,
935 $this->port,
936 $return);
937
938 return $return;
939 }
940 }
941
942 /**
943 * Set the iuserinfo.
944 *
945 * @param string $iuserinfo
946 * @return bool
947 */
948 public function set_userinfo($iuserinfo)
949 {
950 if ($iuserinfo === null)
951 {
952 $this->iuserinfo = null;
953 }
954 else
955 {
956 $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
957 $this->scheme_normalization();
958 }
959
960 return true;
961 }
962
963 /**
964 * Set the ihost. Returns true on success, false on failure (if there are
965 * any invalid characters).
966 *
967 * @param string $ihost
968 * @return bool
969 */
970 public function set_host($ihost)
971 {
972 if ($ihost === null)
973 {
974 $this->ihost = null;
975 return true;
976 }
977 elseif (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']')
978 {
979 if (SimplePie_Net_IPv6::check_ipv6(substr($ihost, 1, -1)))
980 {
981 $this->ihost = '[' . SimplePie_Net_IPv6::compress(substr($ihost, 1, -1)) . ']';
982 }
983 else
984 {
985 $this->ihost = null;
986 return false;
987 }
988 }
989 else
990 {
991 $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
992
993 // Lowercase, but ignore pct-encoded sections (as they should
994 // remain uppercase). This must be done after the previous step
995 // as that can add unescaped characters.
996 $position = 0;
997 $strlen = strlen($ihost);
998 while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen)
999 {
1000 if ($ihost[$position] === '%')
1001 {
1002 $position += 3;
1003 }
1004 else
1005 {
1006 $ihost[$position] = strtolower($ihost[$position]);
1007 $position++;
1008 }
1009 }
1010
1011 $this->ihost = $ihost;
1012 }
1013
1014 $this->scheme_normalization();
1015
1016 return true;
1017 }
1018
1019 /**
1020 * Set the port. Returns true on success, false on failure (if there are
1021 * any invalid characters).
1022 *
1023 * @param string $port
1024 * @return bool
1025 */
1026 public function set_port($port)
1027 {
1028 if ($port === null)
1029 {
1030 $this->port = null;
1031 return true;
1032 }
1033 elseif (strspn($port, '0123456789') === strlen($port))
1034 {
1035 $this->port = (int) $port;
1036 $this->scheme_normalization();
1037 return true;
1038 }
1039 else
1040 {
1041 $this->port = null;
1042 return false;
1043 }
1044 }
1045
1046 /**
1047 * Set the ipath.
1048 *
1049 * @param string $ipath
1050 * @return bool
1051 */
1052 public function set_path($ipath)
1053 {
1054 static $cache;
1055 if (!$cache)
1056 {
1057 $cache = array();
1058 }
1059
1060 $ipath = (string) $ipath;
1061
1062 if (isset($cache[$ipath]))
1063 {
1064 $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
1065 }
1066 else
1067 {
1068 $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
1069 $removed = $this->remove_dot_segments($valid);
1070
1071 $cache[$ipath] = array($valid, $removed);
1072 $this->ipath = ($this->scheme !== null) ? $removed : $valid;
1073 }
1074
1075 $this->scheme_normalization();
1076 return true;
1077 }
1078
1079 /**
1080 * Set the iquery.
1081 *
1082 * @param string $iquery
1083 * @return bool
1084 */
1085 public function set_query($iquery)
1086 {
1087 if ($iquery === null)
1088 {
1089 $this->iquery = null;
1090 }
1091 else
1092 {
1093 $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
1094 $this->scheme_normalization();
1095 }
1096 return true;
1097 }
1098
1099 /**
1100 * Set the ifragment.
1101 *
1102 * @param string $ifragment
1103 * @return bool
1104 */
1105 public function set_fragment($ifragment)
1106 {
1107 if ($ifragment === null)
1108 {
1109 $this->ifragment = null;
1110 }
1111 else
1112 {
1113 $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
1114 $this->scheme_normalization();
1115 }
1116 return true;
1117 }
1118
1119 /**
1120 * Convert an IRI to a URI (or parts thereof)
1121 *
1122 * @return string
1123 */
1124 public function to_uri($string)
1125 {
1126 static $non_ascii;
1127 if (!$non_ascii)
1128 {
1129 $non_ascii = implode('', range("\x80", "\xFF"));
1130 }
1131
1132 $position = 0;
1133 $strlen = strlen($string);
1134 while (($position += strcspn($string, $non_ascii, $position)) < $strlen)
1135 {
1136 $string = substr_replace($string, sprintf('%%%02X', ord($string[$position])), $position, 1);
1137 $position += 3;
1138 $strlen += 2;
1139 }
1140
1141 return $string;
1142 }
1143
1144 /**
1145 * Get the complete IRI
1146 *
1147 * @return string
1148 */
1149 public function get_iri()
1150 {
1151 if (!$this->is_valid())
1152 {
1153 return false;
1154 }
1155
1156 $iri = '';
1157 if ($this->scheme !== null)
1158 {
1159 $iri .= $this->scheme . ':';
1160 }
1161 if (($iauthority = $this->get_iauthority()) !== null)
1162 {
1163 $iri .= '//' . $iauthority;
1164 }
1165 if ($this->ipath !== '')
1166 {
1167 $iri .= $this->ipath;
1168 }
1169 elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '')
1170 {
1171 $iri .= $this->normalization[$this->scheme]['ipath'];
1172 }
1173 if ($this->iquery !== null)
1174 {
1175 $iri .= '?' . $this->iquery;
1176 }
1177 if ($this->ifragment !== null)
1178 {
1179 $iri .= '#' . $this->ifragment;
1180 }
1181
1182 return $iri;
1183 }
1184
1185 /**
1186 * Get the complete URI
1187 *
1188 * @return string
1189 */
1190 public function get_uri()
1191 {
1192 return $this->to_uri($this->get_iri());
1193 }
1194
1195 /**
1196 * Get the complete iauthority
1197 *
1198 * @return string
1199 */
1200 protected function get_iauthority()
1201 {
1202 if ($this->iuserinfo !== null || $this->ihost !== null || $this->port !== null)
1203 {
1204 $iauthority = '';
1205 if ($this->iuserinfo !== null)
1206 {
1207 $iauthority .= $this->iuserinfo . '@';
1208 }
1209 if ($this->ihost !== null)
1210 {
1211 $iauthority .= $this->ihost;
1212 }
1213 if ($this->port !== null)
1214 {
1215 $iauthority .= ':' . $this->port;
1216 }
1217 return $iauthority;
1218 }
1219 else
1220 {
1221 return null;
1222 }
1223 }
1224
1225 /**
1226 * Get the complete authority
1227 *
1228 * @return string
1229 */
1230 protected function get_authority()
1231 {
1232 $iauthority = $this->get_iauthority();
1233 if (is_string($iauthority))
1234 return $this->to_uri($iauthority);
1235 else
1236 return $iauthority;
1237 }
1238}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Item.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Item.php
new file mode 100644
index 00000000..a77574b3
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Item.php
@@ -0,0 +1,2964 @@
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/**
47 * Manages all item-related data
48 *
49 * Used by {@see SimplePie::get_item()} and {@see SimplePie::get_items()}
50 *
51 * This class can be overloaded with {@see SimplePie::set_item_class()}
52 *
53 * @package SimplePie
54 * @subpackage API
55 */
56class SimplePie_Item
57{
58 /**
59 * Parent feed
60 *
61 * @access private
62 * @var SimplePie
63 */
64 var $feed;
65
66 /**
67 * Raw data
68 *
69 * @access private
70 * @var array
71 */
72 var $data = array();
73
74 /**
75 * Registry object
76 *
77 * @see set_registry
78 * @var SimplePie_Registry
79 */
80 protected $registry;
81
82 /**
83 * Create a new item object
84 *
85 * This is usually used by {@see SimplePie::get_items} and
86 * {@see SimplePie::get_item}. Avoid creating this manually.
87 *
88 * @param SimplePie $feed Parent feed
89 * @param array $data Raw data
90 */
91 public function __construct($feed, $data)
92 {
93 $this->feed = $feed;
94 $this->data = $data;
95 }
96
97 /**
98 * Set the registry handler
99 *
100 * This is usually used by {@see SimplePie_Registry::create}
101 *
102 * @since 1.3
103 * @param SimplePie_Registry $registry
104 */
105 public function set_registry(SimplePie_Registry $registry)
106 {
107 $this->registry = $registry;
108 }
109
110 /**
111 * Get a string representation of the item
112 *
113 * @return string
114 */
115 public function __toString()
116 {
117 return md5(serialize($this->data));
118 }
119
120 /**
121 * Remove items that link back to this before destroying this object
122 */
123 public function __destruct()
124 {
125 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
126 {
127 unset($this->feed);
128 }
129 }
130
131 /**
132 * Get data for an item-level element
133 *
134 * This method allows you to get access to ANY element/attribute that is a
135 * sub-element of the item/entry tag.
136 *
137 * See {@see SimplePie::get_feed_tags()} for a description of the return value
138 *
139 * @since 1.0
140 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
141 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
142 * @param string $tag Tag name
143 * @return array
144 */
145 public function get_item_tags($namespace, $tag)
146 {
147 if (isset($this->data['child'][$namespace][$tag]))
148 {
149 return $this->data['child'][$namespace][$tag];
150 }
151 else
152 {
153 return null;
154 }
155 }
156
157 /**
158 * Get the base URL value from the parent feed
159 *
160 * Uses `<xml:base>`
161 *
162 * @param array $element
163 * @return string
164 */
165 public function get_base($element = array())
166 {
167 return $this->feed->get_base($element);
168 }
169
170 /**
171 * Sanitize feed data
172 *
173 * @access private
174 * @see SimplePie::sanitize()
175 * @param string $data Data to sanitize
176 * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
177 * @param string $base Base URL to resolve URLs against
178 * @return string Sanitized data
179 */
180 public function sanitize($data, $type, $base = '')
181 {
182 return $this->feed->sanitize($data, $type, $base);
183 }
184
185 /**
186 * Get the parent feed
187 *
188 * Note: this may not work as you think for multifeeds!
189 *
190 * @link http://simplepie.org/faq/typical_multifeed_gotchas#missing_data_from_feed
191 * @since 1.0
192 * @return SimplePie
193 */
194 public function get_feed()
195 {
196 return $this->feed;
197 }
198
199 /**
200 * Get the unique identifier for the item
201 *
202 * This is usually used when writing code to check for new items in a feed.
203 *
204 * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
205 * for RDF. If none of these are supplied (or `$hash` is true), creates an
206 * MD5 hash based on the permalink and title. If either of those are not
207 * supplied, creates a hash based on the full feed data.
208 *
209 * @since Beta 2
210 * @param boolean $hash Should we force using a hash instead of the supplied ID?
211 * @return string
212 */
213 public function get_id($hash = false)
214 {
215 if (!$hash)
216 {
217 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
218 {
219 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
220 }
221 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
222 {
223 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
224 }
225 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
226 {
227 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
228 }
229 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
230 {
231 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
232 }
233 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
234 {
235 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
236 }
237 elseif (isset($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about']))
238 {
239 return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
240 }
241 elseif (($return = $this->get_permalink()) !== null)
242 {
243 return $return;
244 }
245 elseif (($return = $this->get_title()) !== null)
246 {
247 return $return;
248 }
249 }
250 if ($this->get_permalink() !== null || $this->get_title() !== null)
251 {
252 return md5($this->get_permalink() . $this->get_title());
253 }
254 else
255 {
256 return md5(serialize($this->data));
257 }
258 }
259
260 /**
261 * Get the title of the item
262 *
263 * Uses `<atom:title>`, `<title>` or `<dc:title>`
264 *
265 * @since Beta 2 (previously called `get_item_title` since 0.8)
266 * @return string|null
267 */
268 public function get_title()
269 {
270 if (!isset($this->data['title']))
271 {
272 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
273 {
274 $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
275 }
276 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
277 {
278 $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
279 }
280 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
281 {
282 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
283 }
284 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
285 {
286 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
287 }
288 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
289 {
290 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
291 }
292 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
293 {
294 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
295 }
296 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
297 {
298 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
299 }
300 else
301 {
302 $this->data['title'] = null;
303 }
304 }
305 return $this->data['title'];
306 }
307
308 /**
309 * Get the content for the item
310 *
311 * Prefers summaries over full content , but will return full content if a
312 * summary does not exist.
313 *
314 * To prefer full content instead, use {@see get_content}
315 *
316 * Uses `<atom:summary>`, `<description>`, `<dc:description>` or
317 * `<itunes:subtitle>`
318 *
319 * @since 0.8
320 * @param boolean $description_only Should we avoid falling back to the content?
321 * @return string|null
322 */
323 public function get_description($description_only = false)
324 {
325 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
326 {
327 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
328 }
329 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
330 {
331 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
332 }
333 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
334 {
335 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
336 }
337 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
338 {
339 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
340 }
341 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
342 {
343 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
344 }
345 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
346 {
347 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
348 }
349 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
350 {
351 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
352 }
353 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
354 {
355 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
356 }
357 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
358 {
359 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
360 }
361
362 elseif (!$description_only)
363 {
364 return $this->get_content(true);
365 }
366 else
367 {
368 return null;
369 }
370 }
371
372 /**
373 * Get the content for the item
374 *
375 * Prefers full content over summaries, but will return a summary if full
376 * content does not exist.
377 *
378 * To prefer summaries instead, use {@see get_description}
379 *
380 * Uses `<atom:content>` or `<content:encoded>` (RSS 1.0 Content Module)
381 *
382 * @since 1.0
383 * @param boolean $content_only Should we avoid falling back to the description?
384 * @return string|null
385 */
386 public function get_content($content_only = false)
387 {
388 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
389 {
390 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_content_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
391 }
392 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
393 {
394 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
395 }
396 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
397 {
398 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
399 }
400 elseif (!$content_only)
401 {
402 return $this->get_description(true);
403 }
404 else
405 {
406 return null;
407 }
408 }
409
410 /**
411 * Get a category for the item
412 *
413 * @since Beta 3 (previously called `get_categories()` since Beta 2)
414 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
415 * @return SimplePie_Category|null
416 */
417 public function get_category($key = 0)
418 {
419 $categories = $this->get_categories();
420 if (isset($categories[$key]))
421 {
422 return $categories[$key];
423 }
424 else
425 {
426 return null;
427 }
428 }
429
430 /**
431 * Get all categories for the item
432 *
433 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
434 *
435 * @since Beta 3
436 * @return array|null List of {@see SimplePie_Category} objects
437 */
438 public function get_categories()
439 {
440 $categories = array();
441
442 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
443 {
444 $term = null;
445 $scheme = null;
446 $label = null;
447 if (isset($category['attribs']['']['term']))
448 {
449 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
450 }
451 if (isset($category['attribs']['']['scheme']))
452 {
453 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
454 }
455 if (isset($category['attribs']['']['label']))
456 {
457 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
458 }
459 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
460 }
461 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
462 {
463 // This is really the label, but keep this as the term also for BC.
464 // Label will also work on retrieving because that falls back to term.
465 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
466 if (isset($category['attribs']['']['domain']))
467 {
468 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
469 }
470 else
471 {
472 $scheme = null;
473 }
474 $categories[] = $this->registry->create('Category', array($term, $scheme, null));
475 }
476 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
477 {
478 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
479 }
480 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
481 {
482 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
483 }
484
485 if (!empty($categories))
486 {
487 return array_unique($categories);
488 }
489 else
490 {
491 return null;
492 }
493 }
494
495 /**
496 * Get an author for the item
497 *
498 * @since Beta 2
499 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
500 * @return SimplePie_Author|null
501 */
502 public function get_author($key = 0)
503 {
504 $authors = $this->get_authors();
505 if (isset($authors[$key]))
506 {
507 return $authors[$key];
508 }
509 else
510 {
511 return null;
512 }
513 }
514
515 /**
516 * Get a contributor for the item
517 *
518 * @since 1.1
519 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
520 * @return SimplePie_Author|null
521 */
522 public function get_contributor($key = 0)
523 {
524 $contributors = $this->get_contributors();
525 if (isset($contributors[$key]))
526 {
527 return $contributors[$key];
528 }
529 else
530 {
531 return null;
532 }
533 }
534
535 /**
536 * Get all contributors for the item
537 *
538 * Uses `<atom:contributor>`
539 *
540 * @since 1.1
541 * @return array|null List of {@see SimplePie_Author} objects
542 */
543 public function get_contributors()
544 {
545 $contributors = array();
546 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
547 {
548 $name = null;
549 $uri = null;
550 $email = null;
551 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
552 {
553 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
554 }
555 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
556 {
557 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
558 }
559 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
560 {
561 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
562 }
563 if ($name !== null || $email !== null || $uri !== null)
564 {
565 $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
566 }
567 }
568 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
569 {
570 $name = null;
571 $url = null;
572 $email = null;
573 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
574 {
575 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
576 }
577 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
578 {
579 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
580 }
581 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
582 {
583 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
584 }
585 if ($name !== null || $email !== null || $url !== null)
586 {
587 $contributors[] = $this->registry->create('Author', array($name, $url, $email));
588 }
589 }
590
591 if (!empty($contributors))
592 {
593 return array_unique($contributors);
594 }
595 else
596 {
597 return null;
598 }
599 }
600
601 /**
602 * Get all authors for the item
603 *
604 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
605 *
606 * @since Beta 2
607 * @return array|null List of {@see SimplePie_Author} objects
608 */
609 public function get_authors()
610 {
611 $authors = array();
612 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
613 {
614 $name = null;
615 $uri = null;
616 $email = null;
617 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
618 {
619 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
620 }
621 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
622 {
623 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
624 }
625 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
626 {
627 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
628 }
629 if ($name !== null || $email !== null || $uri !== null)
630 {
631 $authors[] = $this->registry->create('Author', array($name, $uri, $email));
632 }
633 }
634 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
635 {
636 $name = null;
637 $url = null;
638 $email = null;
639 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
640 {
641 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
642 }
643 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
644 {
645 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
646 }
647 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
648 {
649 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
650 }
651 if ($name !== null || $email !== null || $url !== null)
652 {
653 $authors[] = $this->registry->create('Author', array($name, $url, $email));
654 }
655 }
656 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
657 {
658 $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)));
659 }
660 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
661 {
662 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
663 }
664 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
665 {
666 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
667 }
668 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
669 {
670 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
671 }
672
673 if (!empty($authors))
674 {
675 return array_unique($authors);
676 }
677 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
678 {
679 return $authors;
680 }
681 elseif ($authors = $this->feed->get_authors())
682 {
683 return $authors;
684 }
685 else
686 {
687 return null;
688 }
689 }
690
691 /**
692 * Get the copyright info for the item
693 *
694 * Uses `<atom:rights>` or `<dc:rights>`
695 *
696 * @since 1.1
697 * @return string
698 */
699 public function get_copyright()
700 {
701 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
702 {
703 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
704 }
705 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
706 {
707 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
708 }
709 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
710 {
711 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
712 }
713 else
714 {
715 return null;
716 }
717 }
718
719 /**
720 * Get the posting date/time for the item
721 *
722 * Uses `<atom:published>`, `<atom:updated>`, `<atom:issued>`,
723 * `<atom:modified>`, `<pubDate>` or `<dc:date>`
724 *
725 * Note: obeys PHP's timezone setting. To get a UTC date/time, use
726 * {@see get_gmdate}
727 *
728 * @since Beta 2 (previously called `get_item_date` since 0.8)
729 *
730 * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
731 * @return int|string|null
732 */
733 public function get_date($date_format = 'j F Y, g:i a')
734 {
735 if (!isset($this->data['date']))
736 {
737 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
738 {
739 $this->data['date']['raw'] = $return[0]['data'];
740 }
741 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
742 {
743 $this->data['date']['raw'] = $return[0]['data'];
744 }
745 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
746 {
747 $this->data['date']['raw'] = $return[0]['data'];
748 }
749 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
750 {
751 $this->data['date']['raw'] = $return[0]['data'];
752 }
753 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
754 {
755 $this->data['date']['raw'] = $return[0]['data'];
756 }
757 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
758 {
759 $this->data['date']['raw'] = $return[0]['data'];
760 }
761 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
762 {
763 $this->data['date']['raw'] = $return[0]['data'];
764 }
765 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
766 {
767 $this->data['date']['raw'] = $return[0]['data'];
768 }
769
770 if (!empty($this->data['date']['raw']))
771 {
772 $parser = $this->registry->call('Parse_Date', 'get');
773 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
774 }
775 else
776 {
777 $this->data['date'] = null;
778 }
779 }
780 if ($this->data['date'])
781 {
782 $date_format = (string) $date_format;
783 switch ($date_format)
784 {
785 case '':
786 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
787
788 case 'U':
789 return $this->data['date']['parsed'];
790
791 default:
792 return date($date_format, $this->data['date']['parsed']);
793 }
794 }
795 else
796 {
797 return null;
798 }
799 }
800
801 /**
802 * Get the update date/time for the item
803 *
804 * Uses `<atom:updated>`
805 *
806 * Note: obeys PHP's timezone setting. To get a UTC date/time, use
807 * {@see get_gmdate}
808 *
809 * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
810 * @return int|string|null
811 */
812 public function get_updated_date($date_format = 'j F Y, g:i a')
813 {
814 if (!isset($this->data['updated']))
815 {
816 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
817 {
818 $this->data['updated']['raw'] = $return[0]['data'];
819 }
820
821 if (!empty($this->data['updated']['raw']))
822 {
823 $parser = $this->registry->call('Parse_Date', 'get');
824 $this->data['updated']['parsed'] = $parser->parse($this->data['date']['raw']);
825 }
826 else
827 {
828 $this->data['updated'] = null;
829 }
830 }
831 if ($this->data['updated'])
832 {
833 $date_format = (string) $date_format;
834 switch ($date_format)
835 {
836 case '':
837 return $this->sanitize($this->data['updated']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
838
839 case 'U':
840 return $this->data['updated']['parsed'];
841
842 default:
843 return date($date_format, $this->data['updated']['parsed']);
844 }
845 }
846 else
847 {
848 return null;
849 }
850 }
851
852 /**
853 * Get the localized posting date/time for the item
854 *
855 * Returns the date formatted in the localized language. To display in
856 * languages other than the server's default, you need to change the locale
857 * with {@link http://php.net/setlocale setlocale()}. The available
858 * localizations depend on which ones are installed on your web server.
859 *
860 * @since 1.0
861 *
862 * @param string $date_format Supports any PHP date format from {@see http://php.net/strftime} (empty for the raw data)
863 * @return int|string|null
864 */
865 public function get_local_date($date_format = '%c')
866 {
867 if (!$date_format)
868 {
869 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
870 }
871 elseif (($date = $this->get_date('U')) !== null && $date !== false)
872 {
873 return strftime($date_format, $date);
874 }
875 else
876 {
877 return null;
878 }
879 }
880
881 /**
882 * Get the posting date/time for the item (UTC time)
883 *
884 * @see get_date
885 * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
886 * @return int|string|null
887 */
888 public function get_gmdate($date_format = 'j F Y, g:i a')
889 {
890 $date = $this->get_date('U');
891 if ($date === null)
892 {
893 return null;
894 }
895
896 return gmdate($date_format, $date);
897 }
898
899 /**
900 * Get the update date/time for the item (UTC time)
901 *
902 * @see get_updated_date
903 * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
904 * @return int|string|null
905 */
906 public function get_updated_gmdate($date_format = 'j F Y, g:i a')
907 {
908 $date = $this->get_updated_date('U');
909 if ($date === null)
910 {
911 return null;
912 }
913
914 return gmdate($date_format, $date);
915 }
916
917 /**
918 * Get the permalink for the item
919 *
920 * Returns the first link available with a relationship of "alternate".
921 * Identical to {@see get_link()} with key 0
922 *
923 * @see get_link
924 * @since 0.8
925 * @return string|null Permalink URL
926 */
927 public function get_permalink()
928 {
929 $link = $this->get_link();
930 $enclosure = $this->get_enclosure(0);
931 if ($link !== null)
932 {
933 return $link;
934 }
935 elseif ($enclosure !== null)
936 {
937 return $enclosure->get_link();
938 }
939 else
940 {
941 return null;
942 }
943 }
944
945 /**
946 * Get a single link for the item
947 *
948 * @since Beta 3
949 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
950 * @param string $rel The relationship of the link to return
951 * @return string|null Link URL
952 */
953 public function get_link($key = 0, $rel = 'alternate')
954 {
955 $links = $this->get_links($rel);
956 if ($links[$key] !== null)
957 {
958 return $links[$key];
959 }
960 else
961 {
962 return null;
963 }
964 }
965
966 /**
967 * Get all links for the item
968 *
969 * Uses `<atom:link>`, `<link>` or `<guid>`
970 *
971 * @since Beta 2
972 * @param string $rel The relationship of links to return
973 * @return array|null Links found for the item (strings)
974 */
975 public function get_links($rel = 'alternate')
976 {
977 if (!isset($this->data['links']))
978 {
979 $this->data['links'] = array();
980 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
981 {
982 if (isset($link['attribs']['']['href']))
983 {
984 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
985 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
986
987 }
988 }
989 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
990 {
991 if (isset($link['attribs']['']['href']))
992 {
993 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
994 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
995 }
996 }
997 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
998 {
999 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
1000 }
1001 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
1002 {
1003 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
1004 }
1005 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
1006 {
1007 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
1008 }
1009 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
1010 {
1011 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
1012 {
1013 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
1014 }
1015 }
1016
1017 $keys = array_keys($this->data['links']);
1018 foreach ($keys as $key)
1019 {
1020 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
1021 {
1022 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
1023 {
1024 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
1025 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
1026 }
1027 else
1028 {
1029 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
1030 }
1031 }
1032 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
1033 {
1034 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
1035 }
1036 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
1037 }
1038 }
1039 if (isset($this->data['links'][$rel]))
1040 {
1041 return $this->data['links'][$rel];
1042 }
1043 else
1044 {
1045 return null;
1046 }
1047 }
1048
1049 /**
1050 * Get an enclosure from the item
1051 *
1052 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
1053 *
1054 * @since Beta 2
1055 * @todo Add ability to prefer one type of content over another (in a media group).
1056 * @param int $key The enclosure that you want to return. Remember that arrays begin with 0, not 1
1057 * @return SimplePie_Enclosure|null
1058 */
1059 public function get_enclosure($key = 0, $prefer = null)
1060 {
1061 $enclosures = $this->get_enclosures();
1062 if (isset($enclosures[$key]))
1063 {
1064 return $enclosures[$key];
1065 }
1066 else
1067 {
1068 return null;
1069 }
1070 }
1071
1072 /**
1073 * Get all available enclosures (podcasts, etc.)
1074 *
1075 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
1076 *
1077 * At this point, we're pretty much assuming that all enclosures for an item
1078 * are the same content. Anything else is too complicated to
1079 * properly support.
1080 *
1081 * @since Beta 2
1082 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
1083 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
1084 * @return array|null List of SimplePie_Enclosure items
1085 */
1086 public function get_enclosures()
1087 {
1088 if (!isset($this->data['enclosures']))
1089 {
1090 $this->data['enclosures'] = array();
1091
1092 // Elements
1093 $captions_parent = null;
1094 $categories_parent = null;
1095 $copyrights_parent = null;
1096 $credits_parent = null;
1097 $description_parent = null;
1098 $duration_parent = null;
1099 $hashes_parent = null;
1100 $keywords_parent = null;
1101 $player_parent = null;
1102 $ratings_parent = null;
1103 $restrictions_parent = null;
1104 $thumbnails_parent = null;
1105 $title_parent = null;
1106
1107 // Let's do the channel and item-level ones first, and just re-use them if we need to.
1108 $parent = $this->get_feed();
1109
1110 // CAPTIONS
1111 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
1112 {
1113 foreach ($captions as $caption)
1114 {
1115 $caption_type = null;
1116 $caption_lang = null;
1117 $caption_startTime = null;
1118 $caption_endTime = null;
1119 $caption_text = null;
1120 if (isset($caption['attribs']['']['type']))
1121 {
1122 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1123 }
1124 if (isset($caption['attribs']['']['lang']))
1125 {
1126 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
1127 }
1128 if (isset($caption['attribs']['']['start']))
1129 {
1130 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
1131 }
1132 if (isset($caption['attribs']['']['end']))
1133 {
1134 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
1135 }
1136 if (isset($caption['data']))
1137 {
1138 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1139 }
1140 $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
1141 }
1142 }
1143 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
1144 {
1145 foreach ($captions as $caption)
1146 {
1147 $caption_type = null;
1148 $caption_lang = null;
1149 $caption_startTime = null;
1150 $caption_endTime = null;
1151 $caption_text = null;
1152 if (isset($caption['attribs']['']['type']))
1153 {
1154 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1155 }
1156 if (isset($caption['attribs']['']['lang']))
1157 {
1158 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
1159 }
1160 if (isset($caption['attribs']['']['start']))
1161 {
1162 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
1163 }
1164 if (isset($caption['attribs']['']['end']))
1165 {
1166 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
1167 }
1168 if (isset($caption['data']))
1169 {
1170 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1171 }
1172 $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
1173 }
1174 }
1175 if (is_array($captions_parent))
1176 {
1177 $captions_parent = array_values(array_unique($captions_parent));
1178 }
1179
1180 // CATEGORIES
1181 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
1182 {
1183 $term = null;
1184 $scheme = null;
1185 $label = null;
1186 if (isset($category['data']))
1187 {
1188 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1189 }
1190 if (isset($category['attribs']['']['scheme']))
1191 {
1192 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1193 }
1194 else
1195 {
1196 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1197 }
1198 if (isset($category['attribs']['']['label']))
1199 {
1200 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
1201 }
1202 $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
1203 }
1204 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
1205 {
1206 $term = null;
1207 $scheme = null;
1208 $label = null;
1209 if (isset($category['data']))
1210 {
1211 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1212 }
1213 if (isset($category['attribs']['']['scheme']))
1214 {
1215 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1216 }
1217 else
1218 {
1219 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1220 }
1221 if (isset($category['attribs']['']['label']))
1222 {
1223 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
1224 }
1225 $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
1226 }
1227 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
1228 {
1229 $term = null;
1230 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
1231 $label = null;
1232 if (isset($category['attribs']['']['text']))
1233 {
1234 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
1235 }
1236 $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
1237
1238 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
1239 {
1240 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
1241 {
1242 if (isset($subcategory['attribs']['']['text']))
1243 {
1244 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
1245 }
1246 $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
1247 }
1248 }
1249 }
1250 if (is_array($categories_parent))
1251 {
1252 $categories_parent = array_values(array_unique($categories_parent));
1253 }
1254
1255 // COPYRIGHT
1256 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
1257 {
1258 $copyright_url = null;
1259 $copyright_label = null;
1260 if (isset($copyright[0]['attribs']['']['url']))
1261 {
1262 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
1263 }
1264 if (isset($copyright[0]['data']))
1265 {
1266 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1267 }
1268 $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
1269 }
1270 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
1271 {
1272 $copyright_url = null;
1273 $copyright_label = null;
1274 if (isset($copyright[0]['attribs']['']['url']))
1275 {
1276 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
1277 }
1278 if (isset($copyright[0]['data']))
1279 {
1280 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1281 }
1282 $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
1283 }
1284
1285 // CREDITS
1286 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
1287 {
1288 foreach ($credits as $credit)
1289 {
1290 $credit_role = null;
1291 $credit_scheme = null;
1292 $credit_name = null;
1293 if (isset($credit['attribs']['']['role']))
1294 {
1295 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
1296 }
1297 if (isset($credit['attribs']['']['scheme']))
1298 {
1299 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1300 }
1301 else
1302 {
1303 $credit_scheme = 'urn:ebu';
1304 }
1305 if (isset($credit['data']))
1306 {
1307 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1308 }
1309 $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
1310 }
1311 }
1312 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
1313 {
1314 foreach ($credits as $credit)
1315 {
1316 $credit_role = null;
1317 $credit_scheme = null;
1318 $credit_name = null;
1319 if (isset($credit['attribs']['']['role']))
1320 {
1321 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
1322 }
1323 if (isset($credit['attribs']['']['scheme']))
1324 {
1325 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1326 }
1327 else
1328 {
1329 $credit_scheme = 'urn:ebu';
1330 }
1331 if (isset($credit['data']))
1332 {
1333 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1334 }
1335 $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
1336 }
1337 }
1338 if (is_array($credits_parent))
1339 {
1340 $credits_parent = array_values(array_unique($credits_parent));
1341 }
1342
1343 // DESCRIPTION
1344 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
1345 {
1346 if (isset($description_parent[0]['data']))
1347 {
1348 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1349 }
1350 }
1351 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
1352 {
1353 if (isset($description_parent[0]['data']))
1354 {
1355 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1356 }
1357 }
1358
1359 // DURATION
1360 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
1361 {
1362 $seconds = null;
1363 $minutes = null;
1364 $hours = null;
1365 if (isset($duration_parent[0]['data']))
1366 {
1367 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
1368 if (sizeof($temp) > 0)
1369 {
1370 $seconds = (int) array_pop($temp);
1371 }
1372 if (sizeof($temp) > 0)
1373 {
1374 $minutes = (int) array_pop($temp);
1375 $seconds += $minutes * 60;
1376 }
1377 if (sizeof($temp) > 0)
1378 {
1379 $hours = (int) array_pop($temp);
1380 $seconds += $hours * 3600;
1381 }
1382 unset($temp);
1383 $duration_parent = $seconds;
1384 }
1385 }
1386
1387 // HASHES
1388 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
1389 {
1390 foreach ($hashes_iterator as $hash)
1391 {
1392 $value = null;
1393 $algo = null;
1394 if (isset($hash['data']))
1395 {
1396 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1397 }
1398 if (isset($hash['attribs']['']['algo']))
1399 {
1400 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
1401 }
1402 else
1403 {
1404 $algo = 'md5';
1405 }
1406 $hashes_parent[] = $algo.':'.$value;
1407 }
1408 }
1409 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
1410 {
1411 foreach ($hashes_iterator as $hash)
1412 {
1413 $value = null;
1414 $algo = null;
1415 if (isset($hash['data']))
1416 {
1417 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1418 }
1419 if (isset($hash['attribs']['']['algo']))
1420 {
1421 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
1422 }
1423 else
1424 {
1425 $algo = 'md5';
1426 }
1427 $hashes_parent[] = $algo.':'.$value;
1428 }
1429 }
1430 if (is_array($hashes_parent))
1431 {
1432 $hashes_parent = array_values(array_unique($hashes_parent));
1433 }
1434
1435 // KEYWORDS
1436 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
1437 {
1438 if (isset($keywords[0]['data']))
1439 {
1440 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
1441 foreach ($temp as $word)
1442 {
1443 $keywords_parent[] = trim($word);
1444 }
1445 }
1446 unset($temp);
1447 }
1448 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
1449 {
1450 if (isset($keywords[0]['data']))
1451 {
1452 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
1453 foreach ($temp as $word)
1454 {
1455 $keywords_parent[] = trim($word);
1456 }
1457 }
1458 unset($temp);
1459 }
1460 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
1461 {
1462 if (isset($keywords[0]['data']))
1463 {
1464 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
1465 foreach ($temp as $word)
1466 {
1467 $keywords_parent[] = trim($word);
1468 }
1469 }
1470 unset($temp);
1471 }
1472 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
1473 {
1474 if (isset($keywords[0]['data']))
1475 {
1476 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
1477 foreach ($temp as $word)
1478 {
1479 $keywords_parent[] = trim($word);
1480 }
1481 }
1482 unset($temp);
1483 }
1484 if (is_array($keywords_parent))
1485 {
1486 $keywords_parent = array_values(array_unique($keywords_parent));
1487 }
1488
1489 // PLAYER
1490 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
1491 {
1492 if (isset($player_parent[0]['attribs']['']['url']))
1493 {
1494 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
1495 }
1496 }
1497 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
1498 {
1499 if (isset($player_parent[0]['attribs']['']['url']))
1500 {
1501 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
1502 }
1503 }
1504
1505 // RATINGS
1506 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
1507 {
1508 foreach ($ratings as $rating)
1509 {
1510 $rating_scheme = null;
1511 $rating_value = null;
1512 if (isset($rating['attribs']['']['scheme']))
1513 {
1514 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1515 }
1516 else
1517 {
1518 $rating_scheme = 'urn:simple';
1519 }
1520 if (isset($rating['data']))
1521 {
1522 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1523 }
1524 $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
1525 }
1526 }
1527 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
1528 {
1529 foreach ($ratings as $rating)
1530 {
1531 $rating_scheme = 'urn:itunes';
1532 $rating_value = null;
1533 if (isset($rating['data']))
1534 {
1535 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1536 }
1537 $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
1538 }
1539 }
1540 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
1541 {
1542 foreach ($ratings as $rating)
1543 {
1544 $rating_scheme = null;
1545 $rating_value = null;
1546 if (isset($rating['attribs']['']['scheme']))
1547 {
1548 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1549 }
1550 else
1551 {
1552 $rating_scheme = 'urn:simple';
1553 }
1554 if (isset($rating['data']))
1555 {
1556 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1557 }
1558 $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
1559 }
1560 }
1561 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
1562 {
1563 foreach ($ratings as $rating)
1564 {
1565 $rating_scheme = 'urn:itunes';
1566 $rating_value = null;
1567 if (isset($rating['data']))
1568 {
1569 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1570 }
1571 $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
1572 }
1573 }
1574 if (is_array($ratings_parent))
1575 {
1576 $ratings_parent = array_values(array_unique($ratings_parent));
1577 }
1578
1579 // RESTRICTIONS
1580 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
1581 {
1582 foreach ($restrictions as $restriction)
1583 {
1584 $restriction_relationship = null;
1585 $restriction_type = null;
1586 $restriction_value = null;
1587 if (isset($restriction['attribs']['']['relationship']))
1588 {
1589 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
1590 }
1591 if (isset($restriction['attribs']['']['type']))
1592 {
1593 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1594 }
1595 if (isset($restriction['data']))
1596 {
1597 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1598 }
1599 $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
1600 }
1601 }
1602 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
1603 {
1604 foreach ($restrictions as $restriction)
1605 {
1606 $restriction_relationship = 'allow';
1607 $restriction_type = null;
1608 $restriction_value = 'itunes';
1609 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
1610 {
1611 $restriction_relationship = 'deny';
1612 }
1613 $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
1614 }
1615 }
1616 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
1617 {
1618 foreach ($restrictions as $restriction)
1619 {
1620 $restriction_relationship = null;
1621 $restriction_type = null;
1622 $restriction_value = null;
1623 if (isset($restriction['attribs']['']['relationship']))
1624 {
1625 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
1626 }
1627 if (isset($restriction['attribs']['']['type']))
1628 {
1629 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1630 }
1631 if (isset($restriction['data']))
1632 {
1633 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1634 }
1635 $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
1636 }
1637 }
1638 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
1639 {
1640 foreach ($restrictions as $restriction)
1641 {
1642 $restriction_relationship = 'allow';
1643 $restriction_type = null;
1644 $restriction_value = 'itunes';
1645 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
1646 {
1647 $restriction_relationship = 'deny';
1648 }
1649 $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
1650 }
1651 }
1652 if (is_array($restrictions_parent))
1653 {
1654 $restrictions_parent = array_values(array_unique($restrictions_parent));
1655 }
1656 else
1657 {
1658 $restrictions_parent = array(new SimplePie_Restriction('allow', null, 'default'));
1659 }
1660
1661 // THUMBNAILS
1662 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
1663 {
1664 foreach ($thumbnails as $thumbnail)
1665 {
1666 if (isset($thumbnail['attribs']['']['url']))
1667 {
1668 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
1669 }
1670 }
1671 }
1672 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
1673 {
1674 foreach ($thumbnails as $thumbnail)
1675 {
1676 if (isset($thumbnail['attribs']['']['url']))
1677 {
1678 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
1679 }
1680 }
1681 }
1682
1683 // TITLES
1684 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
1685 {
1686 if (isset($title_parent[0]['data']))
1687 {
1688 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1689 }
1690 }
1691 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
1692 {
1693 if (isset($title_parent[0]['data']))
1694 {
1695 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1696 }
1697 }
1698
1699 // Clear the memory
1700 unset($parent);
1701
1702 // Attributes
1703 $bitrate = null;
1704 $channels = null;
1705 $duration = null;
1706 $expression = null;
1707 $framerate = null;
1708 $height = null;
1709 $javascript = null;
1710 $lang = null;
1711 $length = null;
1712 $medium = null;
1713 $samplingrate = null;
1714 $type = null;
1715 $url = null;
1716 $width = null;
1717
1718 // Elements
1719 $captions = null;
1720 $categories = null;
1721 $copyrights = null;
1722 $credits = null;
1723 $description = null;
1724 $hashes = null;
1725 $keywords = null;
1726 $player = null;
1727 $ratings = null;
1728 $restrictions = null;
1729 $thumbnails = null;
1730 $title = null;
1731
1732 // If we have media:group tags, loop through them.
1733 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
1734 {
1735 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
1736 {
1737 // If we have media:content tags, loop through them.
1738 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
1739 {
1740 if (isset($content['attribs']['']['url']))
1741 {
1742 // Attributes
1743 $bitrate = null;
1744 $channels = null;
1745 $duration = null;
1746 $expression = null;
1747 $framerate = null;
1748 $height = null;
1749 $javascript = null;
1750 $lang = null;
1751 $length = null;
1752 $medium = null;
1753 $samplingrate = null;
1754 $type = null;
1755 $url = null;
1756 $width = null;
1757
1758 // Elements
1759 $captions = null;
1760 $categories = null;
1761 $copyrights = null;
1762 $credits = null;
1763 $description = null;
1764 $hashes = null;
1765 $keywords = null;
1766 $player = null;
1767 $ratings = null;
1768 $restrictions = null;
1769 $thumbnails = null;
1770 $title = null;
1771
1772 // Start checking the attributes of media:content
1773 if (isset($content['attribs']['']['bitrate']))
1774 {
1775 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
1776 }
1777 if (isset($content['attribs']['']['channels']))
1778 {
1779 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
1780 }
1781 if (isset($content['attribs']['']['duration']))
1782 {
1783 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
1784 }
1785 else
1786 {
1787 $duration = $duration_parent;
1788 }
1789 if (isset($content['attribs']['']['expression']))
1790 {
1791 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
1792 }
1793 if (isset($content['attribs']['']['framerate']))
1794 {
1795 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
1796 }
1797 if (isset($content['attribs']['']['height']))
1798 {
1799 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
1800 }
1801 if (isset($content['attribs']['']['lang']))
1802 {
1803 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
1804 }
1805 if (isset($content['attribs']['']['fileSize']))
1806 {
1807 $length = ceil($content['attribs']['']['fileSize']);
1808 }
1809 if (isset($content['attribs']['']['medium']))
1810 {
1811 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
1812 }
1813 if (isset($content['attribs']['']['samplingrate']))
1814 {
1815 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
1816 }
1817 if (isset($content['attribs']['']['type']))
1818 {
1819 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1820 }
1821 if (isset($content['attribs']['']['width']))
1822 {
1823 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
1824 }
1825 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
1826
1827 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
1828
1829 // CAPTIONS
1830 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
1831 {
1832 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
1833 {
1834 $caption_type = null;
1835 $caption_lang = null;
1836 $caption_startTime = null;
1837 $caption_endTime = null;
1838 $caption_text = null;
1839 if (isset($caption['attribs']['']['type']))
1840 {
1841 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1842 }
1843 if (isset($caption['attribs']['']['lang']))
1844 {
1845 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
1846 }
1847 if (isset($caption['attribs']['']['start']))
1848 {
1849 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
1850 }
1851 if (isset($caption['attribs']['']['end']))
1852 {
1853 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
1854 }
1855 if (isset($caption['data']))
1856 {
1857 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1858 }
1859 $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
1860 }
1861 if (is_array($captions))
1862 {
1863 $captions = array_values(array_unique($captions));
1864 }
1865 }
1866 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
1867 {
1868 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
1869 {
1870 $caption_type = null;
1871 $caption_lang = null;
1872 $caption_startTime = null;
1873 $caption_endTime = null;
1874 $caption_text = null;
1875 if (isset($caption['attribs']['']['type']))
1876 {
1877 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
1878 }
1879 if (isset($caption['attribs']['']['lang']))
1880 {
1881 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
1882 }
1883 if (isset($caption['attribs']['']['start']))
1884 {
1885 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
1886 }
1887 if (isset($caption['attribs']['']['end']))
1888 {
1889 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
1890 }
1891 if (isset($caption['data']))
1892 {
1893 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1894 }
1895 $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
1896 }
1897 if (is_array($captions))
1898 {
1899 $captions = array_values(array_unique($captions));
1900 }
1901 }
1902 else
1903 {
1904 $captions = $captions_parent;
1905 }
1906
1907 // CATEGORIES
1908 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
1909 {
1910 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
1911 {
1912 $term = null;
1913 $scheme = null;
1914 $label = null;
1915 if (isset($category['data']))
1916 {
1917 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1918 }
1919 if (isset($category['attribs']['']['scheme']))
1920 {
1921 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1922 }
1923 else
1924 {
1925 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1926 }
1927 if (isset($category['attribs']['']['label']))
1928 {
1929 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
1930 }
1931 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
1932 }
1933 }
1934 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
1935 {
1936 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
1937 {
1938 $term = null;
1939 $scheme = null;
1940 $label = null;
1941 if (isset($category['data']))
1942 {
1943 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1944 }
1945 if (isset($category['attribs']['']['scheme']))
1946 {
1947 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
1948 }
1949 else
1950 {
1951 $scheme = 'http://search.yahoo.com/mrss/category_schema';
1952 }
1953 if (isset($category['attribs']['']['label']))
1954 {
1955 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
1956 }
1957 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
1958 }
1959 }
1960 if (is_array($categories) && is_array($categories_parent))
1961 {
1962 $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
1963 }
1964 elseif (is_array($categories))
1965 {
1966 $categories = array_values(array_unique($categories));
1967 }
1968 elseif (is_array($categories_parent))
1969 {
1970 $categories = array_values(array_unique($categories_parent));
1971 }
1972
1973 // COPYRIGHTS
1974 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
1975 {
1976 $copyright_url = null;
1977 $copyright_label = null;
1978 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
1979 {
1980 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
1981 }
1982 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
1983 {
1984 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1985 }
1986 $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
1987 }
1988 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
1989 {
1990 $copyright_url = null;
1991 $copyright_label = null;
1992 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
1993 {
1994 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
1995 }
1996 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
1997 {
1998 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
1999 }
2000 $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
2001 }
2002 else
2003 {
2004 $copyrights = $copyrights_parent;
2005 }
2006
2007 // CREDITS
2008 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
2009 {
2010 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
2011 {
2012 $credit_role = null;
2013 $credit_scheme = null;
2014 $credit_name = null;
2015 if (isset($credit['attribs']['']['role']))
2016 {
2017 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
2018 }
2019 if (isset($credit['attribs']['']['scheme']))
2020 {
2021 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2022 }
2023 else
2024 {
2025 $credit_scheme = 'urn:ebu';
2026 }
2027 if (isset($credit['data']))
2028 {
2029 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2030 }
2031 $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
2032 }
2033 if (is_array($credits))
2034 {
2035 $credits = array_values(array_unique($credits));
2036 }
2037 }
2038 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
2039 {
2040 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
2041 {
2042 $credit_role = null;
2043 $credit_scheme = null;
2044 $credit_name = null;
2045 if (isset($credit['attribs']['']['role']))
2046 {
2047 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
2048 }
2049 if (isset($credit['attribs']['']['scheme']))
2050 {
2051 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2052 }
2053 else
2054 {
2055 $credit_scheme = 'urn:ebu';
2056 }
2057 if (isset($credit['data']))
2058 {
2059 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2060 }
2061 $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
2062 }
2063 if (is_array($credits))
2064 {
2065 $credits = array_values(array_unique($credits));
2066 }
2067 }
2068 else
2069 {
2070 $credits = $credits_parent;
2071 }
2072
2073 // DESCRIPTION
2074 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
2075 {
2076 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2077 }
2078 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
2079 {
2080 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2081 }
2082 else
2083 {
2084 $description = $description_parent;
2085 }
2086
2087 // HASHES
2088 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
2089 {
2090 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
2091 {
2092 $value = null;
2093 $algo = null;
2094 if (isset($hash['data']))
2095 {
2096 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2097 }
2098 if (isset($hash['attribs']['']['algo']))
2099 {
2100 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
2101 }
2102 else
2103 {
2104 $algo = 'md5';
2105 }
2106 $hashes[] = $algo.':'.$value;
2107 }
2108 if (is_array($hashes))
2109 {
2110 $hashes = array_values(array_unique($hashes));
2111 }
2112 }
2113 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
2114 {
2115 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
2116 {
2117 $value = null;
2118 $algo = null;
2119 if (isset($hash['data']))
2120 {
2121 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2122 }
2123 if (isset($hash['attribs']['']['algo']))
2124 {
2125 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
2126 }
2127 else
2128 {
2129 $algo = 'md5';
2130 }
2131 $hashes[] = $algo.':'.$value;
2132 }
2133 if (is_array($hashes))
2134 {
2135 $hashes = array_values(array_unique($hashes));
2136 }
2137 }
2138 else
2139 {
2140 $hashes = $hashes_parent;
2141 }
2142
2143 // KEYWORDS
2144 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
2145 {
2146 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
2147 {
2148 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
2149 foreach ($temp as $word)
2150 {
2151 $keywords[] = trim($word);
2152 }
2153 unset($temp);
2154 }
2155 if (is_array($keywords))
2156 {
2157 $keywords = array_values(array_unique($keywords));
2158 }
2159 }
2160 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
2161 {
2162 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
2163 {
2164 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
2165 foreach ($temp as $word)
2166 {
2167 $keywords[] = trim($word);
2168 }
2169 unset($temp);
2170 }
2171 if (is_array($keywords))
2172 {
2173 $keywords = array_values(array_unique($keywords));
2174 }
2175 }
2176 else
2177 {
2178 $keywords = $keywords_parent;
2179 }
2180
2181 // PLAYER
2182 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
2183 {
2184 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2185 }
2186 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
2187 {
2188 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2189 }
2190 else
2191 {
2192 $player = $player_parent;
2193 }
2194
2195 // RATINGS
2196 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
2197 {
2198 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
2199 {
2200 $rating_scheme = null;
2201 $rating_value = null;
2202 if (isset($rating['attribs']['']['scheme']))
2203 {
2204 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2205 }
2206 else
2207 {
2208 $rating_scheme = 'urn:simple';
2209 }
2210 if (isset($rating['data']))
2211 {
2212 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2213 }
2214 $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
2215 }
2216 if (is_array($ratings))
2217 {
2218 $ratings = array_values(array_unique($ratings));
2219 }
2220 }
2221 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
2222 {
2223 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
2224 {
2225 $rating_scheme = null;
2226 $rating_value = null;
2227 if (isset($rating['attribs']['']['scheme']))
2228 {
2229 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2230 }
2231 else
2232 {
2233 $rating_scheme = 'urn:simple';
2234 }
2235 if (isset($rating['data']))
2236 {
2237 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2238 }
2239 $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
2240 }
2241 if (is_array($ratings))
2242 {
2243 $ratings = array_values(array_unique($ratings));
2244 }
2245 }
2246 else
2247 {
2248 $ratings = $ratings_parent;
2249 }
2250
2251 // RESTRICTIONS
2252 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
2253 {
2254 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
2255 {
2256 $restriction_relationship = null;
2257 $restriction_type = null;
2258 $restriction_value = null;
2259 if (isset($restriction['attribs']['']['relationship']))
2260 {
2261 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
2262 }
2263 if (isset($restriction['attribs']['']['type']))
2264 {
2265 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2266 }
2267 if (isset($restriction['data']))
2268 {
2269 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2270 }
2271 $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
2272 }
2273 if (is_array($restrictions))
2274 {
2275 $restrictions = array_values(array_unique($restrictions));
2276 }
2277 }
2278 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
2279 {
2280 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
2281 {
2282 $restriction_relationship = null;
2283 $restriction_type = null;
2284 $restriction_value = null;
2285 if (isset($restriction['attribs']['']['relationship']))
2286 {
2287 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
2288 }
2289 if (isset($restriction['attribs']['']['type']))
2290 {
2291 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2292 }
2293 if (isset($restriction['data']))
2294 {
2295 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2296 }
2297 $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
2298 }
2299 if (is_array($restrictions))
2300 {
2301 $restrictions = array_values(array_unique($restrictions));
2302 }
2303 }
2304 else
2305 {
2306 $restrictions = $restrictions_parent;
2307 }
2308
2309 // THUMBNAILS
2310 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
2311 {
2312 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
2313 {
2314 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2315 }
2316 if (is_array($thumbnails))
2317 {
2318 $thumbnails = array_values(array_unique($thumbnails));
2319 }
2320 }
2321 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
2322 {
2323 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
2324 {
2325 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2326 }
2327 if (is_array($thumbnails))
2328 {
2329 $thumbnails = array_values(array_unique($thumbnails));
2330 }
2331 }
2332 else
2333 {
2334 $thumbnails = $thumbnails_parent;
2335 }
2336
2337 // TITLES
2338 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
2339 {
2340 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2341 }
2342 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
2343 {
2344 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2345 }
2346 else
2347 {
2348 $title = $title_parent;
2349 }
2350
2351 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
2352 }
2353 }
2354 }
2355 }
2356
2357 // If we have standalone media:content tags, loop through them.
2358 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
2359 {
2360 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
2361 {
2362 if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
2363 {
2364 // Attributes
2365 $bitrate = null;
2366 $channels = null;
2367 $duration = null;
2368 $expression = null;
2369 $framerate = null;
2370 $height = null;
2371 $javascript = null;
2372 $lang = null;
2373 $length = null;
2374 $medium = null;
2375 $samplingrate = null;
2376 $type = null;
2377 $url = null;
2378 $width = null;
2379
2380 // Elements
2381 $captions = null;
2382 $categories = null;
2383 $copyrights = null;
2384 $credits = null;
2385 $description = null;
2386 $hashes = null;
2387 $keywords = null;
2388 $player = null;
2389 $ratings = null;
2390 $restrictions = null;
2391 $thumbnails = null;
2392 $title = null;
2393
2394 // Start checking the attributes of media:content
2395 if (isset($content['attribs']['']['bitrate']))
2396 {
2397 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
2398 }
2399 if (isset($content['attribs']['']['channels']))
2400 {
2401 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
2402 }
2403 if (isset($content['attribs']['']['duration']))
2404 {
2405 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
2406 }
2407 else
2408 {
2409 $duration = $duration_parent;
2410 }
2411 if (isset($content['attribs']['']['expression']))
2412 {
2413 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
2414 }
2415 if (isset($content['attribs']['']['framerate']))
2416 {
2417 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
2418 }
2419 if (isset($content['attribs']['']['height']))
2420 {
2421 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
2422 }
2423 if (isset($content['attribs']['']['lang']))
2424 {
2425 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2426 }
2427 if (isset($content['attribs']['']['fileSize']))
2428 {
2429 $length = ceil($content['attribs']['']['fileSize']);
2430 }
2431 if (isset($content['attribs']['']['medium']))
2432 {
2433 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
2434 }
2435 if (isset($content['attribs']['']['samplingrate']))
2436 {
2437 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
2438 }
2439 if (isset($content['attribs']['']['type']))
2440 {
2441 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2442 }
2443 if (isset($content['attribs']['']['width']))
2444 {
2445 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
2446 }
2447 if (isset($content['attribs']['']['url']))
2448 {
2449 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2450 }
2451 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
2452
2453 // CAPTIONS
2454 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
2455 {
2456 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
2457 {
2458 $caption_type = null;
2459 $caption_lang = null;
2460 $caption_startTime = null;
2461 $caption_endTime = null;
2462 $caption_text = null;
2463 if (isset($caption['attribs']['']['type']))
2464 {
2465 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2466 }
2467 if (isset($caption['attribs']['']['lang']))
2468 {
2469 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2470 }
2471 if (isset($caption['attribs']['']['start']))
2472 {
2473 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
2474 }
2475 if (isset($caption['attribs']['']['end']))
2476 {
2477 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
2478 }
2479 if (isset($caption['data']))
2480 {
2481 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2482 }
2483 $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
2484 }
2485 if (is_array($captions))
2486 {
2487 $captions = array_values(array_unique($captions));
2488 }
2489 }
2490 else
2491 {
2492 $captions = $captions_parent;
2493 }
2494
2495 // CATEGORIES
2496 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
2497 {
2498 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
2499 {
2500 $term = null;
2501 $scheme = null;
2502 $label = null;
2503 if (isset($category['data']))
2504 {
2505 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2506 }
2507 if (isset($category['attribs']['']['scheme']))
2508 {
2509 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2510 }
2511 else
2512 {
2513 $scheme = 'http://search.yahoo.com/mrss/category_schema';
2514 }
2515 if (isset($category['attribs']['']['label']))
2516 {
2517 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2518 }
2519 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
2520 }
2521 }
2522 if (is_array($categories) && is_array($categories_parent))
2523 {
2524 $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
2525 }
2526 elseif (is_array($categories))
2527 {
2528 $categories = array_values(array_unique($categories));
2529 }
2530 elseif (is_array($categories_parent))
2531 {
2532 $categories = array_values(array_unique($categories_parent));
2533 }
2534 else
2535 {
2536 $categories = null;
2537 }
2538
2539 // COPYRIGHTS
2540 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
2541 {
2542 $copyright_url = null;
2543 $copyright_label = null;
2544 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
2545 {
2546 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
2547 }
2548 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
2549 {
2550 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2551 }
2552 $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
2553 }
2554 else
2555 {
2556 $copyrights = $copyrights_parent;
2557 }
2558
2559 // CREDITS
2560 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
2561 {
2562 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
2563 {
2564 $credit_role = null;
2565 $credit_scheme = null;
2566 $credit_name = null;
2567 if (isset($credit['attribs']['']['role']))
2568 {
2569 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
2570 }
2571 if (isset($credit['attribs']['']['scheme']))
2572 {
2573 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2574 }
2575 else
2576 {
2577 $credit_scheme = 'urn:ebu';
2578 }
2579 if (isset($credit['data']))
2580 {
2581 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2582 }
2583 $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
2584 }
2585 if (is_array($credits))
2586 {
2587 $credits = array_values(array_unique($credits));
2588 }
2589 }
2590 else
2591 {
2592 $credits = $credits_parent;
2593 }
2594
2595 // DESCRIPTION
2596 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
2597 {
2598 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2599 }
2600 else
2601 {
2602 $description = $description_parent;
2603 }
2604
2605 // HASHES
2606 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
2607 {
2608 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
2609 {
2610 $value = null;
2611 $algo = null;
2612 if (isset($hash['data']))
2613 {
2614 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2615 }
2616 if (isset($hash['attribs']['']['algo']))
2617 {
2618 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
2619 }
2620 else
2621 {
2622 $algo = 'md5';
2623 }
2624 $hashes[] = $algo.':'.$value;
2625 }
2626 if (is_array($hashes))
2627 {
2628 $hashes = array_values(array_unique($hashes));
2629 }
2630 }
2631 else
2632 {
2633 $hashes = $hashes_parent;
2634 }
2635
2636 // KEYWORDS
2637 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
2638 {
2639 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
2640 {
2641 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
2642 foreach ($temp as $word)
2643 {
2644 $keywords[] = trim($word);
2645 }
2646 unset($temp);
2647 }
2648 if (is_array($keywords))
2649 {
2650 $keywords = array_values(array_unique($keywords));
2651 }
2652 }
2653 else
2654 {
2655 $keywords = $keywords_parent;
2656 }
2657
2658 // PLAYER
2659 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
2660 {
2661 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2662 }
2663 else
2664 {
2665 $player = $player_parent;
2666 }
2667
2668 // RATINGS
2669 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
2670 {
2671 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
2672 {
2673 $rating_scheme = null;
2674 $rating_value = null;
2675 if (isset($rating['attribs']['']['scheme']))
2676 {
2677 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2678 }
2679 else
2680 {
2681 $rating_scheme = 'urn:simple';
2682 }
2683 if (isset($rating['data']))
2684 {
2685 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2686 }
2687 $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
2688 }
2689 if (is_array($ratings))
2690 {
2691 $ratings = array_values(array_unique($ratings));
2692 }
2693 }
2694 else
2695 {
2696 $ratings = $ratings_parent;
2697 }
2698
2699 // RESTRICTIONS
2700 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
2701 {
2702 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
2703 {
2704 $restriction_relationship = null;
2705 $restriction_type = null;
2706 $restriction_value = null;
2707 if (isset($restriction['attribs']['']['relationship']))
2708 {
2709 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
2710 }
2711 if (isset($restriction['attribs']['']['type']))
2712 {
2713 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2714 }
2715 if (isset($restriction['data']))
2716 {
2717 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2718 }
2719 $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
2720 }
2721 if (is_array($restrictions))
2722 {
2723 $restrictions = array_values(array_unique($restrictions));
2724 }
2725 }
2726 else
2727 {
2728 $restrictions = $restrictions_parent;
2729 }
2730
2731 // THUMBNAILS
2732 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
2733 {
2734 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
2735 {
2736 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
2737 }
2738 if (is_array($thumbnails))
2739 {
2740 $thumbnails = array_values(array_unique($thumbnails));
2741 }
2742 }
2743 else
2744 {
2745 $thumbnails = $thumbnails_parent;
2746 }
2747
2748 // TITLES
2749 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
2750 {
2751 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752 }
2753 else
2754 {
2755 $title = $title_parent;
2756 }
2757
2758 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
2759 }
2760 }
2761 }
2762
2763 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
2764 {
2765 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
2766 {
2767 // Attributes
2768 $bitrate = null;
2769 $channels = null;
2770 $duration = null;
2771 $expression = null;
2772 $framerate = null;
2773 $height = null;
2774 $javascript = null;
2775 $lang = null;
2776 $length = null;
2777 $medium = null;
2778 $samplingrate = null;
2779 $type = null;
2780 $url = null;
2781 $width = null;
2782
2783 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2784 if (isset($link['attribs']['']['type']))
2785 {
2786 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2787 }
2788 if (isset($link['attribs']['']['length']))
2789 {
2790 $length = ceil($link['attribs']['']['length']);
2791 }
2792
2793 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2794 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
2795 }
2796 }
2797
2798 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
2799 {
2800 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
2801 {
2802 // Attributes
2803 $bitrate = null;
2804 $channels = null;
2805 $duration = null;
2806 $expression = null;
2807 $framerate = null;
2808 $height = null;
2809 $javascript = null;
2810 $lang = null;
2811 $length = null;
2812 $medium = null;
2813 $samplingrate = null;
2814 $type = null;
2815 $url = null;
2816 $width = null;
2817
2818 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2819 if (isset($link['attribs']['']['type']))
2820 {
2821 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2822 }
2823 if (isset($link['attribs']['']['length']))
2824 {
2825 $length = ceil($link['attribs']['']['length']);
2826 }
2827
2828 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2829 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
2830 }
2831 }
2832
2833 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
2834 {
2835 if (isset($enclosure[0]['attribs']['']['url']))
2836 {
2837 // Attributes
2838 $bitrate = null;
2839 $channels = null;
2840 $duration = null;
2841 $expression = null;
2842 $framerate = null;
2843 $height = null;
2844 $javascript = null;
2845 $lang = null;
2846 $length = null;
2847 $medium = null;
2848 $samplingrate = null;
2849 $type = null;
2850 $url = null;
2851 $width = null;
2852
2853 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
2854 if (isset($enclosure[0]['attribs']['']['type']))
2855 {
2856 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
2857 }
2858 if (isset($enclosure[0]['attribs']['']['length']))
2859 {
2860 $length = ceil($enclosure[0]['attribs']['']['length']);
2861 }
2862
2863 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2864 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
2865 }
2866 }
2867
2868 if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
2869 {
2870 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
2871 $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
2872 }
2873
2874 $this->data['enclosures'] = array_values(array_unique($this->data['enclosures']));
2875 }
2876 if (!empty($this->data['enclosures']))
2877 {
2878 return $this->data['enclosures'];
2879 }
2880 else
2881 {
2882 return null;
2883 }
2884 }
2885
2886 /**
2887 * Get the latitude coordinates for the item
2888 *
2889 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2890 *
2891 * Uses `<geo:lat>` or `<georss:point>`
2892 *
2893 * @since 1.0
2894 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2895 * @link http://www.georss.org/ GeoRSS
2896 * @return string|null
2897 */
2898 public function get_latitude()
2899 {
2900 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2901 {
2902 return (float) $return[0]['data'];
2903 }
2904 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2905 {
2906 return (float) $match[1];
2907 }
2908 else
2909 {
2910 return null;
2911 }
2912 }
2913
2914 /**
2915 * Get the longitude coordinates for the item
2916 *
2917 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2918 *
2919 * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
2920 *
2921 * @since 1.0
2922 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2923 * @link http://www.georss.org/ GeoRSS
2924 * @return string|null
2925 */
2926 public function get_longitude()
2927 {
2928 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2929 {
2930 return (float) $return[0]['data'];
2931 }
2932 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2933 {
2934 return (float) $return[0]['data'];
2935 }
2936 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2937 {
2938 return (float) $match[2];
2939 }
2940 else
2941 {
2942 return null;
2943 }
2944 }
2945
2946 /**
2947 * Get the `<atom:source>` for the item
2948 *
2949 * @since 1.1
2950 * @return SimplePie_Source|null
2951 */
2952 public function get_source()
2953 {
2954 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
2955 {
2956 return $this->registry->create('Source', array($this, $return[0]));
2957 }
2958 else
2959 {
2960 return null;
2961 }
2962 }
2963}
2964
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 */
53class 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
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Misc.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Misc.php
new file mode 100644
index 00000000..5d7367f6
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Misc.php
@@ -0,0 +1,2247 @@
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 * Miscellanous utilities
47 *
48 * @package SimplePie
49 */
50class SimplePie_Misc
51{
52 public static function time_hms($seconds)
53 {
54 $time = '';
55
56 $hours = floor($seconds / 3600);
57 $remainder = $seconds % 3600;
58 if ($hours > 0)
59 {
60 $time .= $hours.':';
61 }
62
63 $minutes = floor($remainder / 60);
64 $seconds = $remainder % 60;
65 if ($minutes < 10 && $hours > 0)
66 {
67 $minutes = '0' . $minutes;
68 }
69 if ($seconds < 10)
70 {
71 $seconds = '0' . $seconds;
72 }
73
74 $time .= $minutes.':';
75 $time .= $seconds;
76
77 return $time;
78 }
79
80 public static function absolutize_url($relative, $base)
81 {
82 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
83 if ($iri === false)
84 {
85 return false;
86 }
87 return $iri->get_uri();
88 }
89
90 /**
91 * Get a HTML/XML element from a HTML string
92 *
93 * @deprecated Use DOMDocument instead (parsing HTML with regex is bad!)
94 * @param string $realname Element name (including namespace prefix if applicable)
95 * @param string $string HTML document
96 * @return array
97 */
98 public static function get_element($realname, $string)
99 {
100 $return = array();
101 $name = preg_quote($realname, '/');
102 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
103 {
104 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
105 {
106 $return[$i]['tag'] = $realname;
107 $return[$i]['full'] = $matches[$i][0][0];
108 $return[$i]['offset'] = $matches[$i][0][1];
109 if (strlen($matches[$i][3][0]) <= 2)
110 {
111 $return[$i]['self_closing'] = true;
112 }
113 else
114 {
115 $return[$i]['self_closing'] = false;
116 $return[$i]['content'] = $matches[$i][4][0];
117 }
118 $return[$i]['attribs'] = array();
119 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
120 {
121 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
122 {
123 if (count($attribs[$j]) === 2)
124 {
125 $attribs[$j][2] = $attribs[$j][1];
126 }
127 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
128 }
129 }
130 }
131 }
132 return $return;
133 }
134
135 public static function element_implode($element)
136 {
137 $full = "<$element[tag]";
138 foreach ($element['attribs'] as $key => $value)
139 {
140 $key = strtolower($key);
141 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
142 }
143 if ($element['self_closing'])
144 {
145 $full .= ' />';
146 }
147 else
148 {
149 $full .= ">$element[content]</$element[tag]>";
150 }
151 return $full;
152 }
153
154 public static function error($message, $level, $file, $line)
155 {
156 if ((ini_get('error_reporting') & $level) > 0)
157 {
158 switch ($level)
159 {
160 case E_USER_ERROR:
161 $note = 'PHP Error';
162 break;
163 case E_USER_WARNING:
164 $note = 'PHP Warning';
165 break;
166 case E_USER_NOTICE:
167 $note = 'PHP Notice';
168 break;
169 default:
170 $note = 'Unknown Error';
171 break;
172 }
173
174 $log_error = true;
175 if (!function_exists('error_log'))
176 {
177 $log_error = false;
178 }
179
180 $log_file = @ini_get('error_log');
181 if (!empty($log_file) && ('syslog' !== $log_file) && !@is_writable($log_file))
182 {
183 $log_error = false;
184 }
185
186 if ($log_error)
187 {
188 @error_log("$note: $message in $file on line $line", 0);
189 }
190 }
191
192 return $message;
193 }
194
195 public static function fix_protocol($url, $http = 1)
196 {
197 $url = SimplePie_Misc::normalize_url($url);
198 $parsed = SimplePie_Misc::parse_url($url);
199 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
200 {
201 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
202 }
203
204 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
205 {
206 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
207 }
208
209 if ($http === 2 && $parsed['scheme'] !== '')
210 {
211 return "feed:$url";
212 }
213 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
214 {
215 return substr_replace($url, 'podcast', 0, 4);
216 }
217 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
218 {
219 return substr_replace($url, 'itpc', 0, 4);
220 }
221 else
222 {
223 return $url;
224 }
225 }
226
227 public static function parse_url($url)
228 {
229 $iri = new SimplePie_IRI($url);
230 return array(
231 'scheme' => (string) $iri->scheme,
232 'authority' => (string) $iri->authority,
233 'path' => (string) $iri->path,
234 'query' => (string) $iri->query,
235 'fragment' => (string) $iri->fragment
236 );
237 }
238
239 public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
240 {
241 $iri = new SimplePie_IRI('');
242 $iri->scheme = $scheme;
243 $iri->authority = $authority;
244 $iri->path = $path;
245 $iri->query = $query;
246 $iri->fragment = $fragment;
247 return $iri->get_uri();
248 }
249
250 public static function normalize_url($url)
251 {
252 $iri = new SimplePie_IRI($url);
253 return $iri->get_uri();
254 }
255
256 public static function percent_encoding_normalization($match)
257 {
258 $integer = hexdec($match[1]);
259 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
260 {
261 return chr($integer);
262 }
263 else
264 {
265 return strtoupper($match[0]);
266 }
267 }
268
269 /**
270 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
271 *
272 * @static
273 * @param string $string Windows-1252 encoded string
274 * @return string UTF-8 encoded string
275 */
276 public static function windows_1252_to_utf8($string)
277 {
278 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
279
280 return strtr($string, $convert_table);
281 }
282
283 /**
284 * Change a string from one encoding to another
285 *
286 * @param string $data Raw data in $input encoding
287 * @param string $input Encoding of $data
288 * @param string $output Encoding you want
289 * @return string|boolean False if we can't convert it
290 */
291 public static function change_encoding($data, $input, $output)
292 {
293 $input = SimplePie_Misc::encoding($input);
294 $output = SimplePie_Misc::encoding($output);
295
296 // We fail to fail on non US-ASCII bytes
297 if ($input === 'US-ASCII')
298 {
299 static $non_ascii_octects = '';
300 if (!$non_ascii_octects)
301 {
302 for ($i = 0x80; $i <= 0xFF; $i++)
303 {
304 $non_ascii_octects .= chr($i);
305 }
306 }
307 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
308 }
309
310 // This is first, as behaviour of this is completely predictable
311 if ($input === 'windows-1252' && $output === 'UTF-8')
312 {
313 return SimplePie_Misc::windows_1252_to_utf8($data);
314 }
315 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
316 elseif (function_exists('mb_convert_encoding') && ($return = SimplePie_Misc::change_encoding_mbstring($data, $input, $output)))
317 {
318 return $return;
319 }
320 // This is last, as behaviour of this varies with OS userland and PHP version
321 elseif (function_exists('iconv') && ($return = SimplePie_Misc::change_encoding_iconv($data, $input, $output)))
322 {
323 return $return;
324 }
325 // If we can't do anything, just fail
326 else
327 {
328 return false;
329 }
330 }
331
332 protected static function change_encoding_mbstring($data, $input, $output)
333 {
334 if ($input === 'windows-949')
335 {
336 $input = 'EUC-KR';
337 }
338 if ($output === 'windows-949')
339 {
340 $output = 'EUC-KR';
341 }
342 if ($input === 'Windows-31J')
343 {
344 $input = 'SJIS';
345 }
346 if ($output === 'Windows-31J')
347 {
348 $output = 'SJIS';
349 }
350
351 // Check that the encoding is supported
352 if (@mb_convert_encoding("\x80", 'UTF-16BE', $input) === "\x00\x80")
353 {
354 return false;
355 }
356 if (!in_array($input, mb_list_encodings()))
357 {
358 return false;
359 }
360
361 // Let's do some conversion
362 if ($return = @mb_convert_encoding($data, $output, $input))
363 {
364 return $return;
365 }
366
367 return false;
368 }
369
370 protected static function change_encoding_iconv($data, $input, $output)
371 {
372 return @iconv($input, $output, $data);
373 }
374
375 /**
376 * Normalize an encoding name
377 *
378 * This is automatically generated by create.php
379 *
380 * To generate it, run `php create.php` on the command line, and copy the
381 * output to replace this function.
382 *
383 * @param string $charset Character set to standardise
384 * @return string Standardised name
385 */
386 public static function encoding($charset)
387 {
388 // Normalization from UTS #22
389 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
390 {
391 case 'adobestandardencoding':
392 case 'csadobestandardencoding':
393 return 'Adobe-Standard-Encoding';
394
395 case 'adobesymbolencoding':
396 case 'cshppsmath':
397 return 'Adobe-Symbol-Encoding';
398
399 case 'ami1251':
400 case 'amiga1251':
401 return 'Amiga-1251';
402
403 case 'ansix31101983':
404 case 'csat5001983':
405 case 'csiso99naplps':
406 case 'isoir99':
407 case 'naplps':
408 return 'ANSI_X3.110-1983';
409
410 case 'arabic7':
411 case 'asmo449':
412 case 'csiso89asmo449':
413 case 'iso9036':
414 case 'isoir89':
415 return 'ASMO_449';
416
417 case 'big5':
418 case 'csbig5':
419 return 'Big5';
420
421 case 'big5hkscs':
422 return 'Big5-HKSCS';
423
424 case 'bocu1':
425 case 'csbocu1':
426 return 'BOCU-1';
427
428 case 'brf':
429 case 'csbrf':
430 return 'BRF';
431
432 case 'bs4730':
433 case 'csiso4unitedkingdom':
434 case 'gb':
435 case 'iso646gb':
436 case 'isoir4':
437 case 'uk':
438 return 'BS_4730';
439
440 case 'bsviewdata':
441 case 'csiso47bsviewdata':
442 case 'isoir47':
443 return 'BS_viewdata';
444
445 case 'cesu8':
446 case 'cscesu8':
447 return 'CESU-8';
448
449 case 'ca':
450 case 'csa71':
451 case 'csaz243419851':
452 case 'csiso121canadian1':
453 case 'iso646ca':
454 case 'isoir121':
455 return 'CSA_Z243.4-1985-1';
456
457 case 'csa72':
458 case 'csaz243419852':
459 case 'csiso122canadian2':
460 case 'iso646ca2':
461 case 'isoir122':
462 return 'CSA_Z243.4-1985-2';
463
464 case 'csaz24341985gr':
465 case 'csiso123csaz24341985gr':
466 case 'isoir123':
467 return 'CSA_Z243.4-1985-gr';
468
469 case 'csiso139csn369103':
470 case 'csn369103':
471 case 'isoir139':
472 return 'CSN_369103';
473
474 case 'csdecmcs':
475 case 'dec':
476 case 'decmcs':
477 return 'DEC-MCS';
478
479 case 'csiso21german':
480 case 'de':
481 case 'din66003':
482 case 'iso646de':
483 case 'isoir21':
484 return 'DIN_66003';
485
486 case 'csdkus':
487 case 'dkus':
488 return 'dk-us';
489
490 case 'csiso646danish':
491 case 'dk':
492 case 'ds2089':
493 case 'iso646dk':
494 return 'DS_2089';
495
496 case 'csibmebcdicatde':
497 case 'ebcdicatde':
498 return 'EBCDIC-AT-DE';
499
500 case 'csebcdicatdea':
501 case 'ebcdicatdea':
502 return 'EBCDIC-AT-DE-A';
503
504 case 'csebcdiccafr':
505 case 'ebcdiccafr':
506 return 'EBCDIC-CA-FR';
507
508 case 'csebcdicdkno':
509 case 'ebcdicdkno':
510 return 'EBCDIC-DK-NO';
511
512 case 'csebcdicdknoa':
513 case 'ebcdicdknoa':
514 return 'EBCDIC-DK-NO-A';
515
516 case 'csebcdices':
517 case 'ebcdices':
518 return 'EBCDIC-ES';
519
520 case 'csebcdicesa':
521 case 'ebcdicesa':
522 return 'EBCDIC-ES-A';
523
524 case 'csebcdicess':
525 case 'ebcdicess':
526 return 'EBCDIC-ES-S';
527
528 case 'csebcdicfise':
529 case 'ebcdicfise':
530 return 'EBCDIC-FI-SE';
531
532 case 'csebcdicfisea':
533 case 'ebcdicfisea':
534 return 'EBCDIC-FI-SE-A';
535
536 case 'csebcdicfr':
537 case 'ebcdicfr':
538 return 'EBCDIC-FR';
539
540 case 'csebcdicit':
541 case 'ebcdicit':
542 return 'EBCDIC-IT';
543
544 case 'csebcdicpt':
545 case 'ebcdicpt':
546 return 'EBCDIC-PT';
547
548 case 'csebcdicuk':
549 case 'ebcdicuk':
550 return 'EBCDIC-UK';
551
552 case 'csebcdicus':
553 case 'ebcdicus':
554 return 'EBCDIC-US';
555
556 case 'csiso111ecmacyrillic':
557 case 'ecmacyrillic':
558 case 'isoir111':
559 case 'koi8e':
560 return 'ECMA-cyrillic';
561
562 case 'csiso17spanish':
563 case 'es':
564 case 'iso646es':
565 case 'isoir17':
566 return 'ES';
567
568 case 'csiso85spanish2':
569 case 'es2':
570 case 'iso646es2':
571 case 'isoir85':
572 return 'ES2';
573
574 case 'cseucpkdfmtjapanese':
575 case 'eucjp':
576 case 'extendedunixcodepackedformatforjapanese':
577 return 'EUC-JP';
578
579 case 'cseucfixwidjapanese':
580 case 'extendedunixcodefixedwidthforjapanese':
581 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
582
583 case 'gb18030':
584 return 'GB18030';
585
586 case 'chinese':
587 case 'cp936':
588 case 'csgb2312':
589 case 'csiso58gb231280':
590 case 'gb2312':
591 case 'gb231280':
592 case 'gbk':
593 case 'isoir58':
594 case 'ms936':
595 case 'windows936':
596 return 'GBK';
597
598 case 'cn':
599 case 'csiso57gb1988':
600 case 'gb198880':
601 case 'iso646cn':
602 case 'isoir57':
603 return 'GB_1988-80';
604
605 case 'csiso153gost1976874':
606 case 'gost1976874':
607 case 'isoir153':
608 case 'stsev35888':
609 return 'GOST_19768-74';
610
611 case 'csiso150':
612 case 'csiso150greekccitt':
613 case 'greekccitt':
614 case 'isoir150':
615 return 'greek-ccitt';
616
617 case 'csiso88greek7':
618 case 'greek7':
619 case 'isoir88':
620 return 'greek7';
621
622 case 'csiso18greek7old':
623 case 'greek7old':
624 case 'isoir18':
625 return 'greek7-old';
626
627 case 'cshpdesktop':
628 case 'hpdesktop':
629 return 'HP-DeskTop';
630
631 case 'cshplegal':
632 case 'hplegal':
633 return 'HP-Legal';
634
635 case 'cshpmath8':
636 case 'hpmath8':
637 return 'HP-Math8';
638
639 case 'cshppifont':
640 case 'hppifont':
641 return 'HP-Pi-font';
642
643 case 'cshproman8':
644 case 'hproman8':
645 case 'r8':
646 case 'roman8':
647 return 'hp-roman8';
648
649 case 'hzgb2312':
650 return 'HZ-GB-2312';
651
652 case 'csibmsymbols':
653 case 'ibmsymbols':
654 return 'IBM-Symbols';
655
656 case 'csibmthai':
657 case 'ibmthai':
658 return 'IBM-Thai';
659
660 case 'cp37':
661 case 'csibm37':
662 case 'ebcdiccpca':
663 case 'ebcdiccpnl':
664 case 'ebcdiccpus':
665 case 'ebcdiccpwt':
666 case 'ibm37':
667 return 'IBM037';
668
669 case 'cp38':
670 case 'csibm38':
671 case 'ebcdicint':
672 case 'ibm38':
673 return 'IBM038';
674
675 case 'cp273':
676 case 'csibm273':
677 case 'ibm273':
678 return 'IBM273';
679
680 case 'cp274':
681 case 'csibm274':
682 case 'ebcdicbe':
683 case 'ibm274':
684 return 'IBM274';
685
686 case 'cp275':
687 case 'csibm275':
688 case 'ebcdicbr':
689 case 'ibm275':
690 return 'IBM275';
691
692 case 'csibm277':
693 case 'ebcdiccpdk':
694 case 'ebcdiccpno':
695 case 'ibm277':
696 return 'IBM277';
697
698 case 'cp278':
699 case 'csibm278':
700 case 'ebcdiccpfi':
701 case 'ebcdiccpse':
702 case 'ibm278':
703 return 'IBM278';
704
705 case 'cp280':
706 case 'csibm280':
707 case 'ebcdiccpit':
708 case 'ibm280':
709 return 'IBM280';
710
711 case 'cp281':
712 case 'csibm281':
713 case 'ebcdicjpe':
714 case 'ibm281':
715 return 'IBM281';
716
717 case 'cp284':
718 case 'csibm284':
719 case 'ebcdiccpes':
720 case 'ibm284':
721 return 'IBM284';
722
723 case 'cp285':
724 case 'csibm285':
725 case 'ebcdiccpgb':
726 case 'ibm285':
727 return 'IBM285';
728
729 case 'cp290':
730 case 'csibm290':
731 case 'ebcdicjpkana':
732 case 'ibm290':
733 return 'IBM290';
734
735 case 'cp297':
736 case 'csibm297':
737 case 'ebcdiccpfr':
738 case 'ibm297':
739 return 'IBM297';
740
741 case 'cp420':
742 case 'csibm420':
743 case 'ebcdiccpar1':
744 case 'ibm420':
745 return 'IBM420';
746
747 case 'cp423':
748 case 'csibm423':
749 case 'ebcdiccpgr':
750 case 'ibm423':
751 return 'IBM423';
752
753 case 'cp424':
754 case 'csibm424':
755 case 'ebcdiccphe':
756 case 'ibm424':
757 return 'IBM424';
758
759 case '437':
760 case 'cp437':
761 case 'cspc8codepage437':
762 case 'ibm437':
763 return 'IBM437';
764
765 case 'cp500':
766 case 'csibm500':
767 case 'ebcdiccpbe':
768 case 'ebcdiccpch':
769 case 'ibm500':
770 return 'IBM500';
771
772 case 'cp775':
773 case 'cspc775baltic':
774 case 'ibm775':
775 return 'IBM775';
776
777 case '850':
778 case 'cp850':
779 case 'cspc850multilingual':
780 case 'ibm850':
781 return 'IBM850';
782
783 case '851':
784 case 'cp851':
785 case 'csibm851':
786 case 'ibm851':
787 return 'IBM851';
788
789 case '852':
790 case 'cp852':
791 case 'cspcp852':
792 case 'ibm852':
793 return 'IBM852';
794
795 case '855':
796 case 'cp855':
797 case 'csibm855':
798 case 'ibm855':
799 return 'IBM855';
800
801 case '857':
802 case 'cp857':
803 case 'csibm857':
804 case 'ibm857':
805 return 'IBM857';
806
807 case 'ccsid858':
808 case 'cp858':
809 case 'ibm858':
810 case 'pcmultilingual850euro':
811 return 'IBM00858';
812
813 case '860':
814 case 'cp860':
815 case 'csibm860':
816 case 'ibm860':
817 return 'IBM860';
818
819 case '861':
820 case 'cp861':
821 case 'cpis':
822 case 'csibm861':
823 case 'ibm861':
824 return 'IBM861';
825
826 case '862':
827 case 'cp862':
828 case 'cspc862latinhebrew':
829 case 'ibm862':
830 return 'IBM862';
831
832 case '863':
833 case 'cp863':
834 case 'csibm863':
835 case 'ibm863':
836 return 'IBM863';
837
838 case 'cp864':
839 case 'csibm864':
840 case 'ibm864':
841 return 'IBM864';
842
843 case '865':
844 case 'cp865':
845 case 'csibm865':
846 case 'ibm865':
847 return 'IBM865';
848
849 case '866':
850 case 'cp866':
851 case 'csibm866':
852 case 'ibm866':
853 return 'IBM866';
854
855 case 'cp868':
856 case 'cpar':
857 case 'csibm868':
858 case 'ibm868':
859 return 'IBM868';
860
861 case '869':
862 case 'cp869':
863 case 'cpgr':
864 case 'csibm869':
865 case 'ibm869':
866 return 'IBM869';
867
868 case 'cp870':
869 case 'csibm870':
870 case 'ebcdiccproece':
871 case 'ebcdiccpyu':
872 case 'ibm870':
873 return 'IBM870';
874
875 case 'cp871':
876 case 'csibm871':
877 case 'ebcdiccpis':
878 case 'ibm871':
879 return 'IBM871';
880
881 case 'cp880':
882 case 'csibm880':
883 case 'ebcdiccyrillic':
884 case 'ibm880':
885 return 'IBM880';
886
887 case 'cp891':
888 case 'csibm891':
889 case 'ibm891':
890 return 'IBM891';
891
892 case 'cp903':
893 case 'csibm903':
894 case 'ibm903':
895 return 'IBM903';
896
897 case '904':
898 case 'cp904':
899 case 'csibbm904':
900 case 'ibm904':
901 return 'IBM904';
902
903 case 'cp905':
904 case 'csibm905':
905 case 'ebcdiccptr':
906 case 'ibm905':
907 return 'IBM905';
908
909 case 'cp918':
910 case 'csibm918':
911 case 'ebcdiccpar2':
912 case 'ibm918':
913 return 'IBM918';
914
915 case 'ccsid924':
916 case 'cp924':
917 case 'ebcdiclatin9euro':
918 case 'ibm924':
919 return 'IBM00924';
920
921 case 'cp1026':
922 case 'csibm1026':
923 case 'ibm1026':
924 return 'IBM1026';
925
926 case 'ibm1047':
927 return 'IBM1047';
928
929 case 'ccsid1140':
930 case 'cp1140':
931 case 'ebcdicus37euro':
932 case 'ibm1140':
933 return 'IBM01140';
934
935 case 'ccsid1141':
936 case 'cp1141':
937 case 'ebcdicde273euro':
938 case 'ibm1141':
939 return 'IBM01141';
940
941 case 'ccsid1142':
942 case 'cp1142':
943 case 'ebcdicdk277euro':
944 case 'ebcdicno277euro':
945 case 'ibm1142':
946 return 'IBM01142';
947
948 case 'ccsid1143':
949 case 'cp1143':
950 case 'ebcdicfi278euro':
951 case 'ebcdicse278euro':
952 case 'ibm1143':
953 return 'IBM01143';
954
955 case 'ccsid1144':
956 case 'cp1144':
957 case 'ebcdicit280euro':
958 case 'ibm1144':
959 return 'IBM01144';
960
961 case 'ccsid1145':
962 case 'cp1145':
963 case 'ebcdices284euro':
964 case 'ibm1145':
965 return 'IBM01145';
966
967 case 'ccsid1146':
968 case 'cp1146':
969 case 'ebcdicgb285euro':
970 case 'ibm1146':
971 return 'IBM01146';
972
973 case 'ccsid1147':
974 case 'cp1147':
975 case 'ebcdicfr297euro':
976 case 'ibm1147':
977 return 'IBM01147';
978
979 case 'ccsid1148':
980 case 'cp1148':
981 case 'ebcdicinternational500euro':
982 case 'ibm1148':
983 return 'IBM01148';
984
985 case 'ccsid1149':
986 case 'cp1149':
987 case 'ebcdicis871euro':
988 case 'ibm1149':
989 return 'IBM01149';
990
991 case 'csiso143iecp271':
992 case 'iecp271':
993 case 'isoir143':
994 return 'IEC_P27-1';
995
996 case 'csiso49inis':
997 case 'inis':
998 case 'isoir49':
999 return 'INIS';
1000
1001 case 'csiso50inis8':
1002 case 'inis8':
1003 case 'isoir50':
1004 return 'INIS-8';
1005
1006 case 'csiso51iniscyrillic':
1007 case 'iniscyrillic':
1008 case 'isoir51':
1009 return 'INIS-cyrillic';
1010
1011 case 'csinvariant':
1012 case 'invariant':
1013 return 'INVARIANT';
1014
1015 case 'iso2022cn':
1016 return 'ISO-2022-CN';
1017
1018 case 'iso2022cnext':
1019 return 'ISO-2022-CN-EXT';
1020
1021 case 'csiso2022jp':
1022 case 'iso2022jp':
1023 return 'ISO-2022-JP';
1024
1025 case 'csiso2022jp2':
1026 case 'iso2022jp2':
1027 return 'ISO-2022-JP-2';
1028
1029 case 'csiso2022kr':
1030 case 'iso2022kr':
1031 return 'ISO-2022-KR';
1032
1033 case 'cswindows30latin1':
1034 case 'iso88591windows30latin1':
1035 return 'ISO-8859-1-Windows-3.0-Latin-1';
1036
1037 case 'cswindows31latin1':
1038 case 'iso88591windows31latin1':
1039 return 'ISO-8859-1-Windows-3.1-Latin-1';
1040
1041 case 'csisolatin2':
1042 case 'iso88592':
1043 case 'iso885921987':
1044 case 'isoir101':
1045 case 'l2':
1046 case 'latin2':
1047 return 'ISO-8859-2';
1048
1049 case 'cswindows31latin2':
1050 case 'iso88592windowslatin2':
1051 return 'ISO-8859-2-Windows-Latin-2';
1052
1053 case 'csisolatin3':
1054 case 'iso88593':
1055 case 'iso885931988':
1056 case 'isoir109':
1057 case 'l3':
1058 case 'latin3':
1059 return 'ISO-8859-3';
1060
1061 case 'csisolatin4':
1062 case 'iso88594':
1063 case 'iso885941988':
1064 case 'isoir110':
1065 case 'l4':
1066 case 'latin4':
1067 return 'ISO-8859-4';
1068
1069 case 'csisolatincyrillic':
1070 case 'cyrillic':
1071 case 'iso88595':
1072 case 'iso885951988':
1073 case 'isoir144':
1074 return 'ISO-8859-5';
1075
1076 case 'arabic':
1077 case 'asmo708':
1078 case 'csisolatinarabic':
1079 case 'ecma114':
1080 case 'iso88596':
1081 case 'iso885961987':
1082 case 'isoir127':
1083 return 'ISO-8859-6';
1084
1085 case 'csiso88596e':
1086 case 'iso88596e':
1087 return 'ISO-8859-6-E';
1088
1089 case 'csiso88596i':
1090 case 'iso88596i':
1091 return 'ISO-8859-6-I';
1092
1093 case 'csisolatingreek':
1094 case 'ecma118':
1095 case 'elot928':
1096 case 'greek':
1097 case 'greek8':
1098 case 'iso88597':
1099 case 'iso885971987':
1100 case 'isoir126':
1101 return 'ISO-8859-7';
1102
1103 case 'csisolatinhebrew':
1104 case 'hebrew':
1105 case 'iso88598':
1106 case 'iso885981988':
1107 case 'isoir138':
1108 return 'ISO-8859-8';
1109
1110 case 'csiso88598e':
1111 case 'iso88598e':
1112 return 'ISO-8859-8-E';
1113
1114 case 'csiso88598i':
1115 case 'iso88598i':
1116 return 'ISO-8859-8-I';
1117
1118 case 'cswindows31latin5':
1119 case 'iso88599windowslatin5':
1120 return 'ISO-8859-9-Windows-Latin-5';
1121
1122 case 'csisolatin6':
1123 case 'iso885910':
1124 case 'iso8859101992':
1125 case 'isoir157':
1126 case 'l6':
1127 case 'latin6':
1128 return 'ISO-8859-10';
1129
1130 case 'iso885913':
1131 return 'ISO-8859-13';
1132
1133 case 'iso885914':
1134 case 'iso8859141998':
1135 case 'isoceltic':
1136 case 'isoir199':
1137 case 'l8':
1138 case 'latin8':
1139 return 'ISO-8859-14';
1140
1141 case 'iso885915':
1142 case 'latin9':
1143 return 'ISO-8859-15';
1144
1145 case 'iso885916':
1146 case 'iso8859162001':
1147 case 'isoir226':
1148 case 'l10':
1149 case 'latin10':
1150 return 'ISO-8859-16';
1151
1152 case 'iso10646j1':
1153 return 'ISO-10646-J-1';
1154
1155 case 'csunicode':
1156 case 'iso10646ucs2':
1157 return 'ISO-10646-UCS-2';
1158
1159 case 'csucs4':
1160 case 'iso10646ucs4':
1161 return 'ISO-10646-UCS-4';
1162
1163 case 'csunicodeascii':
1164 case 'iso10646ucsbasic':
1165 return 'ISO-10646-UCS-Basic';
1166
1167 case 'csunicodelatin1':
1168 case 'iso10646':
1169 case 'iso10646unicodelatin1':
1170 return 'ISO-10646-Unicode-Latin1';
1171
1172 case 'csiso10646utf1':
1173 case 'iso10646utf1':
1174 return 'ISO-10646-UTF-1';
1175
1176 case 'csiso115481':
1177 case 'iso115481':
1178 case 'isotr115481':
1179 return 'ISO-11548-1';
1180
1181 case 'csiso90':
1182 case 'isoir90':
1183 return 'iso-ir-90';
1184
1185 case 'csunicodeibm1261':
1186 case 'isounicodeibm1261':
1187 return 'ISO-Unicode-IBM-1261';
1188
1189 case 'csunicodeibm1264':
1190 case 'isounicodeibm1264':
1191 return 'ISO-Unicode-IBM-1264';
1192
1193 case 'csunicodeibm1265':
1194 case 'isounicodeibm1265':
1195 return 'ISO-Unicode-IBM-1265';
1196
1197 case 'csunicodeibm1268':
1198 case 'isounicodeibm1268':
1199 return 'ISO-Unicode-IBM-1268';
1200
1201 case 'csunicodeibm1276':
1202 case 'isounicodeibm1276':
1203 return 'ISO-Unicode-IBM-1276';
1204
1205 case 'csiso646basic1983':
1206 case 'iso646basic1983':
1207 case 'ref':
1208 return 'ISO_646.basic:1983';
1209
1210 case 'csiso2intlrefversion':
1211 case 'irv':
1212 case 'iso646irv1983':
1213 case 'isoir2':
1214 return 'ISO_646.irv:1983';
1215
1216 case 'csiso2033':
1217 case 'e13b':
1218 case 'iso20331983':
1219 case 'isoir98':
1220 return 'ISO_2033-1983';
1221
1222 case 'csiso5427cyrillic':
1223 case 'iso5427':
1224 case 'isoir37':
1225 return 'ISO_5427';
1226
1227 case 'iso5427cyrillic1981':
1228 case 'iso54271981':
1229 case 'isoir54':
1230 return 'ISO_5427:1981';
1231
1232 case 'csiso5428greek':
1233 case 'iso54281980':
1234 case 'isoir55':
1235 return 'ISO_5428:1980';
1236
1237 case 'csiso6937add':
1238 case 'iso6937225':
1239 case 'isoir152':
1240 return 'ISO_6937-2-25';
1241
1242 case 'csisotextcomm':
1243 case 'iso69372add':
1244 case 'isoir142':
1245 return 'ISO_6937-2-add';
1246
1247 case 'csiso8859supp':
1248 case 'iso8859supp':
1249 case 'isoir154':
1250 case 'latin125':
1251 return 'ISO_8859-supp';
1252
1253 case 'csiso10367box':
1254 case 'iso10367box':
1255 case 'isoir155':
1256 return 'ISO_10367-box';
1257
1258 case 'csiso15italian':
1259 case 'iso646it':
1260 case 'isoir15':
1261 case 'it':
1262 return 'IT';
1263
1264 case 'csiso13jisc6220jp':
1265 case 'isoir13':
1266 case 'jisc62201969':
1267 case 'jisc62201969jp':
1268 case 'katakana':
1269 case 'x2017':
1270 return 'JIS_C6220-1969-jp';
1271
1272 case 'csiso14jisc6220ro':
1273 case 'iso646jp':
1274 case 'isoir14':
1275 case 'jisc62201969ro':
1276 case 'jp':
1277 return 'JIS_C6220-1969-ro';
1278
1279 case 'csiso42jisc62261978':
1280 case 'isoir42':
1281 case 'jisc62261978':
1282 return 'JIS_C6226-1978';
1283
1284 case 'csiso87jisx208':
1285 case 'isoir87':
1286 case 'jisc62261983':
1287 case 'jisx2081983':
1288 case 'x208':
1289 return 'JIS_C6226-1983';
1290
1291 case 'csiso91jisc62291984a':
1292 case 'isoir91':
1293 case 'jisc62291984a':
1294 case 'jpocra':
1295 return 'JIS_C6229-1984-a';
1296
1297 case 'csiso92jisc62991984b':
1298 case 'iso646jpocrb':
1299 case 'isoir92':
1300 case 'jisc62291984b':
1301 case 'jpocrb':
1302 return 'JIS_C6229-1984-b';
1303
1304 case 'csiso93jis62291984badd':
1305 case 'isoir93':
1306 case 'jisc62291984badd':
1307 case 'jpocrbadd':
1308 return 'JIS_C6229-1984-b-add';
1309
1310 case 'csiso94jis62291984hand':
1311 case 'isoir94':
1312 case 'jisc62291984hand':
1313 case 'jpocrhand':
1314 return 'JIS_C6229-1984-hand';
1315
1316 case 'csiso95jis62291984handadd':
1317 case 'isoir95':
1318 case 'jisc62291984handadd':
1319 case 'jpocrhandadd':
1320 return 'JIS_C6229-1984-hand-add';
1321
1322 case 'csiso96jisc62291984kana':
1323 case 'isoir96':
1324 case 'jisc62291984kana':
1325 return 'JIS_C6229-1984-kana';
1326
1327 case 'csjisencoding':
1328 case 'jisencoding':
1329 return 'JIS_Encoding';
1330
1331 case 'cshalfwidthkatakana':
1332 case 'jisx201':
1333 case 'x201':
1334 return 'JIS_X0201';
1335
1336 case 'csiso159jisx2121990':
1337 case 'isoir159':
1338 case 'jisx2121990':
1339 case 'x212':
1340 return 'JIS_X0212-1990';
1341
1342 case 'csiso141jusib1002':
1343 case 'iso646yu':
1344 case 'isoir141':
1345 case 'js':
1346 case 'jusib1002':
1347 case 'yu':
1348 return 'JUS_I.B1.002';
1349
1350 case 'csiso147macedonian':
1351 case 'isoir147':
1352 case 'jusib1003mac':
1353 case 'macedonian':
1354 return 'JUS_I.B1.003-mac';
1355
1356 case 'csiso146serbian':
1357 case 'isoir146':
1358 case 'jusib1003serb':
1359 case 'serbian':
1360 return 'JUS_I.B1.003-serb';
1361
1362 case 'koi7switched':
1363 return 'KOI7-switched';
1364
1365 case 'cskoi8r':
1366 case 'koi8r':
1367 return 'KOI8-R';
1368
1369 case 'koi8u':
1370 return 'KOI8-U';
1371
1372 case 'csksc5636':
1373 case 'iso646kr':
1374 case 'ksc5636':
1375 return 'KSC5636';
1376
1377 case 'cskz1048':
1378 case 'kz1048':
1379 case 'rk1048':
1380 case 'strk10482002':
1381 return 'KZ-1048';
1382
1383 case 'csiso19latingreek':
1384 case 'isoir19':
1385 case 'latingreek':
1386 return 'latin-greek';
1387
1388 case 'csiso27latingreek1':
1389 case 'isoir27':
1390 case 'latingreek1':
1391 return 'Latin-greek-1';
1392
1393 case 'csiso158lap':
1394 case 'isoir158':
1395 case 'lap':
1396 case 'latinlap':
1397 return 'latin-lap';
1398
1399 case 'csmacintosh':
1400 case 'mac':
1401 case 'macintosh':
1402 return 'macintosh';
1403
1404 case 'csmicrosoftpublishing':
1405 case 'microsoftpublishing':
1406 return 'Microsoft-Publishing';
1407
1408 case 'csmnem':
1409 case 'mnem':
1410 return 'MNEM';
1411
1412 case 'csmnemonic':
1413 case 'mnemonic':
1414 return 'MNEMONIC';
1415
1416 case 'csiso86hungarian':
1417 case 'hu':
1418 case 'iso646hu':
1419 case 'isoir86':
1420 case 'msz77953':
1421 return 'MSZ_7795.3';
1422
1423 case 'csnatsdano':
1424 case 'isoir91':
1425 case 'natsdano':
1426 return 'NATS-DANO';
1427
1428 case 'csnatsdanoadd':
1429 case 'isoir92':
1430 case 'natsdanoadd':
1431 return 'NATS-DANO-ADD';
1432
1433 case 'csnatssefi':
1434 case 'isoir81':
1435 case 'natssefi':
1436 return 'NATS-SEFI';
1437
1438 case 'csnatssefiadd':
1439 case 'isoir82':
1440 case 'natssefiadd':
1441 return 'NATS-SEFI-ADD';
1442
1443 case 'csiso151cuba':
1444 case 'cuba':
1445 case 'iso646cu':
1446 case 'isoir151':
1447 case 'ncnc1081':
1448 return 'NC_NC00-10:81';
1449
1450 case 'csiso69french':
1451 case 'fr':
1452 case 'iso646fr':
1453 case 'isoir69':
1454 case 'nfz62010':
1455 return 'NF_Z_62-010';
1456
1457 case 'csiso25french':
1458 case 'iso646fr1':
1459 case 'isoir25':
1460 case 'nfz620101973':
1461 return 'NF_Z_62-010_(1973)';
1462
1463 case 'csiso60danishnorwegian':
1464 case 'csiso60norwegian1':
1465 case 'iso646no':
1466 case 'isoir60':
1467 case 'no':
1468 case 'ns45511':
1469 return 'NS_4551-1';
1470
1471 case 'csiso61norwegian2':
1472 case 'iso646no2':
1473 case 'isoir61':
1474 case 'no2':
1475 case 'ns45512':
1476 return 'NS_4551-2';
1477
1478 case 'osdebcdicdf3irv':
1479 return 'OSD_EBCDIC_DF03_IRV';
1480
1481 case 'osdebcdicdf41':
1482 return 'OSD_EBCDIC_DF04_1';
1483
1484 case 'osdebcdicdf415':
1485 return 'OSD_EBCDIC_DF04_15';
1486
1487 case 'cspc8danishnorwegian':
1488 case 'pc8danishnorwegian':
1489 return 'PC8-Danish-Norwegian';
1490
1491 case 'cspc8turkish':
1492 case 'pc8turkish':
1493 return 'PC8-Turkish';
1494
1495 case 'csiso16portuguese':
1496 case 'iso646pt':
1497 case 'isoir16':
1498 case 'pt':
1499 return 'PT';
1500
1501 case 'csiso84portuguese2':
1502 case 'iso646pt2':
1503 case 'isoir84':
1504 case 'pt2':
1505 return 'PT2';
1506
1507 case 'cp154':
1508 case 'csptcp154':
1509 case 'cyrillicasian':
1510 case 'pt154':
1511 case 'ptcp154':
1512 return 'PTCP154';
1513
1514 case 'scsu':
1515 return 'SCSU';
1516
1517 case 'csiso10swedish':
1518 case 'fi':
1519 case 'iso646fi':
1520 case 'iso646se':
1521 case 'isoir10':
1522 case 'se':
1523 case 'sen850200b':
1524 return 'SEN_850200_B';
1525
1526 case 'csiso11swedishfornames':
1527 case 'iso646se2':
1528 case 'isoir11':
1529 case 'se2':
1530 case 'sen850200c':
1531 return 'SEN_850200_C';
1532
1533 case 'csiso102t617bit':
1534 case 'isoir102':
1535 case 't617bit':
1536 return 'T.61-7bit';
1537
1538 case 'csiso103t618bit':
1539 case 'isoir103':
1540 case 't61':
1541 case 't618bit':
1542 return 'T.61-8bit';
1543
1544 case 'csiso128t101g2':
1545 case 'isoir128':
1546 case 't101g2':
1547 return 'T.101-G2';
1548
1549 case 'cstscii':
1550 case 'tscii':
1551 return 'TSCII';
1552
1553 case 'csunicode11':
1554 case 'unicode11':
1555 return 'UNICODE-1-1';
1556
1557 case 'csunicode11utf7':
1558 case 'unicode11utf7':
1559 return 'UNICODE-1-1-UTF-7';
1560
1561 case 'csunknown8bit':
1562 case 'unknown8bit':
1563 return 'UNKNOWN-8BIT';
1564
1565 case 'ansix341968':
1566 case 'ansix341986':
1567 case 'ascii':
1568 case 'cp367':
1569 case 'csascii':
1570 case 'ibm367':
1571 case 'iso646irv1991':
1572 case 'iso646us':
1573 case 'isoir6':
1574 case 'us':
1575 case 'usascii':
1576 return 'US-ASCII';
1577
1578 case 'csusdk':
1579 case 'usdk':
1580 return 'us-dk';
1581
1582 case 'utf7':
1583 return 'UTF-7';
1584
1585 case 'utf8':
1586 return 'UTF-8';
1587
1588 case 'utf16':
1589 return 'UTF-16';
1590
1591 case 'utf16be':
1592 return 'UTF-16BE';
1593
1594 case 'utf16le':
1595 return 'UTF-16LE';
1596
1597 case 'utf32':
1598 return 'UTF-32';
1599
1600 case 'utf32be':
1601 return 'UTF-32BE';
1602
1603 case 'utf32le':
1604 return 'UTF-32LE';
1605
1606 case 'csventurainternational':
1607 case 'venturainternational':
1608 return 'Ventura-International';
1609
1610 case 'csventuramath':
1611 case 'venturamath':
1612 return 'Ventura-Math';
1613
1614 case 'csventuraus':
1615 case 'venturaus':
1616 return 'Ventura-US';
1617
1618 case 'csiso70videotexsupp1':
1619 case 'isoir70':
1620 case 'videotexsuppl':
1621 return 'videotex-suppl';
1622
1623 case 'csviqr':
1624 case 'viqr':
1625 return 'VIQR';
1626
1627 case 'csviscii':
1628 case 'viscii':
1629 return 'VISCII';
1630
1631 case 'csshiftjis':
1632 case 'cswindows31j':
1633 case 'mskanji':
1634 case 'shiftjis':
1635 case 'windows31j':
1636 return 'Windows-31J';
1637
1638 case 'iso885911':
1639 case 'tis620':
1640 return 'windows-874';
1641
1642 case 'cseuckr':
1643 case 'csksc56011987':
1644 case 'euckr':
1645 case 'isoir149':
1646 case 'korean':
1647 case 'ksc5601':
1648 case 'ksc56011987':
1649 case 'ksc56011989':
1650 case 'windows949':
1651 return 'windows-949';
1652
1653 case 'windows1250':
1654 return 'windows-1250';
1655
1656 case 'windows1251':
1657 return 'windows-1251';
1658
1659 case 'cp819':
1660 case 'csisolatin1':
1661 case 'ibm819':
1662 case 'iso88591':
1663 case 'iso885911987':
1664 case 'isoir100':
1665 case 'l1':
1666 case 'latin1':
1667 case 'windows1252':
1668 return 'windows-1252';
1669
1670 case 'windows1253':
1671 return 'windows-1253';
1672
1673 case 'csisolatin5':
1674 case 'iso88599':
1675 case 'iso885991989':
1676 case 'isoir148':
1677 case 'l5':
1678 case 'latin5':
1679 case 'windows1254':
1680 return 'windows-1254';
1681
1682 case 'windows1255':
1683 return 'windows-1255';
1684
1685 case 'windows1256':
1686 return 'windows-1256';
1687
1688 case 'windows1257':
1689 return 'windows-1257';
1690
1691 case 'windows1258':
1692 return 'windows-1258';
1693
1694 default:
1695 return $charset;
1696 }
1697 }
1698
1699 public static function get_curl_version()
1700 {
1701 if (is_array($curl = curl_version()))
1702 {
1703 $curl = $curl['version'];
1704 }
1705 elseif (substr($curl, 0, 5) === 'curl/')
1706 {
1707 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
1708 }
1709 elseif (substr($curl, 0, 8) === 'libcurl/')
1710 {
1711 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
1712 }
1713 else
1714 {
1715 $curl = 0;
1716 }
1717 return $curl;
1718 }
1719
1720 /**
1721 * Strip HTML comments
1722 *
1723 * @param string $data Data to strip comments from
1724 * @return string Comment stripped string
1725 */
1726 public static function strip_comments($data)
1727 {
1728 $output = '';
1729 while (($start = strpos($data, '<!--')) !== false)
1730 {
1731 $output .= substr($data, 0, $start);
1732 if (($end = strpos($data, '-->', $start)) !== false)
1733 {
1734 $data = substr_replace($data, '', 0, $end + 3);
1735 }
1736 else
1737 {
1738 $data = '';
1739 }
1740 }
1741 return $output . $data;
1742 }
1743
1744 public static function parse_date($dt)
1745 {
1746 $parser = SimplePie_Parse_Date::get();
1747 return $parser->parse($dt);
1748 }
1749
1750 /**
1751 * Decode HTML entities
1752 *
1753 * @deprecated Use DOMDocument instead
1754 * @param string $data Input data
1755 * @return string Output data
1756 */
1757 public static function entities_decode($data)
1758 {
1759 $decoder = new SimplePie_Decode_HTML_Entities($data);
1760 return $decoder->parse();
1761 }
1762
1763 /**
1764 * Remove RFC822 comments
1765 *
1766 * @param string $data Data to strip comments from
1767 * @return string Comment stripped string
1768 */
1769 public static function uncomment_rfc822($string)
1770 {
1771 $string = (string) $string;
1772 $position = 0;
1773 $length = strlen($string);
1774 $depth = 0;
1775
1776 $output = '';
1777
1778 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
1779 {
1780 $output .= substr($string, $position, $pos - $position);
1781 $position = $pos + 1;
1782 if ($string[$pos - 1] !== '\\')
1783 {
1784 $depth++;
1785 while ($depth && $position < $length)
1786 {
1787 $position += strcspn($string, '()', $position);
1788 if ($string[$position - 1] === '\\')
1789 {
1790 $position++;
1791 continue;
1792 }
1793 elseif (isset($string[$position]))
1794 {
1795 switch ($string[$position])
1796 {
1797 case '(':
1798 $depth++;
1799 break;
1800
1801 case ')':
1802 $depth--;
1803 break;
1804 }
1805 $position++;
1806 }
1807 else
1808 {
1809 break;
1810 }
1811 }
1812 }
1813 else
1814 {
1815 $output .= '(';
1816 }
1817 }
1818 $output .= substr($string, $position);
1819
1820 return $output;
1821 }
1822
1823 public static function parse_mime($mime)
1824 {
1825 if (($pos = strpos($mime, ';')) === false)
1826 {
1827 return trim($mime);
1828 }
1829 else
1830 {
1831 return trim(substr($mime, 0, $pos));
1832 }
1833 }
1834
1835 public static function atom_03_construct_type($attribs)
1836 {
1837 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
1838 {
1839 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
1840 }
1841 else
1842 {
1843 $mode = SIMPLEPIE_CONSTRUCT_NONE;
1844 }
1845 if (isset($attribs['']['type']))
1846 {
1847 switch (strtolower(trim($attribs['']['type'])))
1848 {
1849 case 'text':
1850 case 'text/plain':
1851 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
1852
1853 case 'html':
1854 case 'text/html':
1855 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
1856
1857 case 'xhtml':
1858 case 'application/xhtml+xml':
1859 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
1860
1861 default:
1862 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
1863 }
1864 }
1865 else
1866 {
1867 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
1868 }
1869 }
1870
1871 public static function atom_10_construct_type($attribs)
1872 {
1873 if (isset($attribs['']['type']))
1874 {
1875 switch (strtolower(trim($attribs['']['type'])))
1876 {
1877 case 'text':
1878 return SIMPLEPIE_CONSTRUCT_TEXT;
1879
1880 case 'html':
1881 return SIMPLEPIE_CONSTRUCT_HTML;
1882
1883 case 'xhtml':
1884 return SIMPLEPIE_CONSTRUCT_XHTML;
1885
1886 default:
1887 return SIMPLEPIE_CONSTRUCT_NONE;
1888 }
1889 }
1890 return SIMPLEPIE_CONSTRUCT_TEXT;
1891 }
1892
1893 public static function atom_10_content_construct_type($attribs)
1894 {
1895 if (isset($attribs['']['type']))
1896 {
1897 $type = strtolower(trim($attribs['']['type']));
1898 switch ($type)
1899 {
1900 case 'text':
1901 return SIMPLEPIE_CONSTRUCT_TEXT;
1902
1903 case 'html':
1904 return SIMPLEPIE_CONSTRUCT_HTML;
1905
1906 case 'xhtml':
1907 return SIMPLEPIE_CONSTRUCT_XHTML;
1908 }
1909 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
1910 {
1911 return SIMPLEPIE_CONSTRUCT_NONE;
1912 }
1913 else
1914 {
1915 return SIMPLEPIE_CONSTRUCT_BASE64;
1916 }
1917 }
1918 else
1919 {
1920 return SIMPLEPIE_CONSTRUCT_TEXT;
1921 }
1922 }
1923
1924 public static function is_isegment_nz_nc($string)
1925 {
1926 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
1927 }
1928
1929 public static function space_seperated_tokens($string)
1930 {
1931 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
1932 $string_length = strlen($string);
1933
1934 $position = strspn($string, $space_characters);
1935 $tokens = array();
1936
1937 while ($position < $string_length)
1938 {
1939 $len = strcspn($string, $space_characters, $position);
1940 $tokens[] = substr($string, $position, $len);
1941 $position += $len;
1942 $position += strspn($string, $space_characters, $position);
1943 }
1944
1945 return $tokens;
1946 }
1947
1948 /**
1949 * Converts a unicode codepoint to a UTF-8 character
1950 *
1951 * @static
1952 * @param int $codepoint Unicode codepoint
1953 * @return string UTF-8 character
1954 */
1955 public static function codepoint_to_utf8($codepoint)
1956 {
1957 $codepoint = (int) $codepoint;
1958 if ($codepoint < 0)
1959 {
1960 return false;
1961 }
1962 else if ($codepoint <= 0x7f)
1963 {
1964 return chr($codepoint);
1965 }
1966 else if ($codepoint <= 0x7ff)
1967 {
1968 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
1969 }
1970 else if ($codepoint <= 0xffff)
1971 {
1972 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
1973 }
1974 else if ($codepoint <= 0x10ffff)
1975 {
1976 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
1977 }
1978 else
1979 {
1980 // U+FFFD REPLACEMENT CHARACTER
1981 return "\xEF\xBF\xBD";
1982 }
1983 }
1984
1985 /**
1986 * Similar to parse_str()
1987 *
1988 * Returns an associative array of name/value pairs, where the value is an
1989 * array of values that have used the same name
1990 *
1991 * @static
1992 * @param string $str The input string.
1993 * @return array
1994 */
1995 public static function parse_str($str)
1996 {
1997 $return = array();
1998 $str = explode('&', $str);
1999
2000 foreach ($str as $section)
2001 {
2002 if (strpos($section, '=') !== false)
2003 {
2004 list($name, $value) = explode('=', $section, 2);
2005 $return[urldecode($name)][] = urldecode($value);
2006 }
2007 else
2008 {
2009 $return[urldecode($section)][] = null;
2010 }
2011 }
2012
2013 return $return;
2014 }
2015
2016 /**
2017 * Detect XML encoding, as per XML 1.0 Appendix F.1
2018 *
2019 * @todo Add support for EBCDIC
2020 * @param string $data XML data
2021 * @param SimplePie_Registry $registry Class registry
2022 * @return array Possible encodings
2023 */
2024 public static function xml_encoding($data, $registry)
2025 {
2026 // UTF-32 Big Endian BOM
2027 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
2028 {
2029 $encoding[] = 'UTF-32BE';
2030 }
2031 // UTF-32 Little Endian BOM
2032 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
2033 {
2034 $encoding[] = 'UTF-32LE';
2035 }
2036 // UTF-16 Big Endian BOM
2037 elseif (substr($data, 0, 2) === "\xFE\xFF")
2038 {
2039 $encoding[] = 'UTF-16BE';
2040 }
2041 // UTF-16 Little Endian BOM
2042 elseif (substr($data, 0, 2) === "\xFF\xFE")
2043 {
2044 $encoding[] = 'UTF-16LE';
2045 }
2046 // UTF-8 BOM
2047 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
2048 {
2049 $encoding[] = 'UTF-8';
2050 }
2051 // UTF-32 Big Endian Without BOM
2052 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
2053 {
2054 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
2055 {
2056 $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')));
2057 if ($parser->parse())
2058 {
2059 $encoding[] = $parser->encoding;
2060 }
2061 }
2062 $encoding[] = 'UTF-32BE';
2063 }
2064 // UTF-32 Little Endian Without BOM
2065 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
2066 {
2067 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
2068 {
2069 $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')));
2070 if ($parser->parse())
2071 {
2072 $encoding[] = $parser->encoding;
2073 }
2074 }
2075 $encoding[] = 'UTF-32LE';
2076 }
2077 // UTF-16 Big Endian Without BOM
2078 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
2079 {
2080 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
2081 {
2082 $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')));
2083 if ($parser->parse())
2084 {
2085 $encoding[] = $parser->encoding;
2086 }
2087 }
2088 $encoding[] = 'UTF-16BE';
2089 }
2090 // UTF-16 Little Endian Without BOM
2091 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
2092 {
2093 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
2094 {
2095 $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')));
2096 if ($parser->parse())
2097 {
2098 $encoding[] = $parser->encoding;
2099 }
2100 }
2101 $encoding[] = 'UTF-16LE';
2102 }
2103 // US-ASCII (or superset)
2104 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
2105 {
2106 if ($pos = strpos($data, "\x3F\x3E"))
2107 {
2108 $parser = $registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
2109 if ($parser->parse())
2110 {
2111 $encoding[] = $parser->encoding;
2112 }
2113 }
2114 $encoding[] = 'UTF-8';
2115 }
2116 // Fallback to UTF-8
2117 else
2118 {
2119 $encoding[] = 'UTF-8';
2120 }
2121 return $encoding;
2122 }
2123
2124 public static function output_javascript()
2125 {
2126 if (function_exists('ob_gzhandler'))
2127 {
2128 ob_start('ob_gzhandler');
2129 }
2130 header('Content-type: text/javascript; charset: UTF-8');
2131 header('Cache-Control: must-revalidate');
2132 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
2133 ?>
2134function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
2135 if (placeholder != '') {
2136 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
2137 }
2138 else {
2139 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
2140 }
2141}
2142
2143function embed_flash(bgcolor, width, height, link, loop, type) {
2144 document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
2145}
2146
2147function embed_flv(width, height, link, placeholder, loop, player) {
2148 document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
2149}
2150
2151function embed_wmedia(width, height, link) {
2152 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
2153}
2154 <?php
2155 }
2156
2157 /**
2158 * Get the SimplePie build timestamp
2159 *
2160 * Uses the git index if it exists, otherwise uses the modification time
2161 * of the newest file.
2162 */
2163 public static function get_build()
2164 {
2165 $root = dirname(dirname(__FILE__));
2166 if (file_exists($root . '/.git/index'))
2167 {
2168 return filemtime($root . '/.git/index');
2169 }
2170 elseif (file_exists($root . '/SimplePie'))
2171 {
2172 $time = 0;
2173 foreach (glob($root . '/SimplePie/*.php') as $file)
2174 {
2175 if (($mtime = filemtime($file)) > $time)
2176 {
2177 $time = $mtime;
2178 }
2179 }
2180 return $time;
2181 }
2182 elseif (file_exists(dirname(__FILE__) . '/Core.php'))
2183 {
2184 return filemtime(dirname(__FILE__) . '/Core.php');
2185 }
2186 else
2187 {
2188 return filemtime(__FILE__);
2189 }
2190 }
2191
2192 /**
2193 * Format debugging information
2194 */
2195 public static function debug(&$sp)
2196 {
2197 $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
2198 $info .= 'PHP ' . PHP_VERSION . "\n";
2199 if ($sp->error() !== null)
2200 {
2201 $info .= 'Error occurred: ' . $sp->error() . "\n";
2202 }
2203 else
2204 {
2205 $info .= "No error found.\n";
2206 }
2207 $info .= "Extensions:\n";
2208 $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
2209 foreach ($extensions as $ext)
2210 {
2211 if (extension_loaded($ext))
2212 {
2213 $info .= " $ext loaded\n";
2214 switch ($ext)
2215 {
2216 case 'pcre':
2217 $info .= ' Version ' . PCRE_VERSION . "\n";
2218 break;
2219 case 'curl':
2220 $version = curl_version();
2221 $info .= ' Version ' . $version['version'] . "\n";
2222 break;
2223 case 'mbstring':
2224 $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";
2225 break;
2226 case 'iconv':
2227 $info .= ' Version ' . ICONV_VERSION . "\n";
2228 break;
2229 case 'xml':
2230 $info .= ' Version ' . LIBXML_DOTTED_VERSION . "\n";
2231 break;
2232 }
2233 }
2234 else
2235 {
2236 $info .= " $ext not loaded\n";
2237 }
2238 }
2239 return $info;
2240 }
2241
2242 public static function silence_errors($num, $str)
2243 {
2244 // No-op
2245 }
2246}
2247
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Net/IPv6.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Net/IPv6.php
new file mode 100644
index 00000000..da80d8ac
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Net/IPv6.php
@@ -0,0 +1,276 @@
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/**
47 * Class to validate and to work with IPv6 addresses.
48 *
49 * @package SimplePie
50 * @subpackage HTTP
51 * @copyright 2003-2005 The PHP Group
52 * @license http://www.opensource.org/licenses/bsd-license.php
53 * @link http://pear.php.net/package/Net_IPv6
54 * @author Alexander Merz <alexander.merz@web.de>
55 * @author elfrink at introweb dot nl
56 * @author Josh Peck <jmp at joshpeck dot org>
57 * @author Geoffrey Sneddon <geoffers@gmail.com>
58 */
59class SimplePie_Net_IPv6
60{
61 /**
62 * Uncompresses an IPv6 address
63 *
64 * RFC 4291 allows you to compress concecutive zero pieces in an address to
65 * '::'. This method expects a valid IPv6 address and expands the '::' to
66 * the required number of zero pieces.
67 *
68 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
69 * ::1 -> 0:0:0:0:0:0:0:1
70 *
71 * @author Alexander Merz <alexander.merz@web.de>
72 * @author elfrink at introweb dot nl
73 * @author Josh Peck <jmp at joshpeck dot org>
74 * @copyright 2003-2005 The PHP Group
75 * @license http://www.opensource.org/licenses/bsd-license.php
76 * @param string $ip An IPv6 address
77 * @return string The uncompressed IPv6 address
78 */
79 public static function uncompress($ip)
80 {
81 $c1 = -1;
82 $c2 = -1;
83 if (substr_count($ip, '::') === 1)
84 {
85 list($ip1, $ip2) = explode('::', $ip);
86 if ($ip1 === '')
87 {
88 $c1 = -1;
89 }
90 else
91 {
92 $c1 = substr_count($ip1, ':');
93 }
94 if ($ip2 === '')
95 {
96 $c2 = -1;
97 }
98 else
99 {
100 $c2 = substr_count($ip2, ':');
101 }
102 if (strpos($ip2, '.') !== false)
103 {
104 $c2++;
105 }
106 // ::
107 if ($c1 === -1 && $c2 === -1)
108 {
109 $ip = '0:0:0:0:0:0:0:0';
110 }
111 // ::xxx
112 else if ($c1 === -1)
113 {
114 $fill = str_repeat('0:', 7 - $c2);
115 $ip = str_replace('::', $fill, $ip);
116 }
117 // xxx::
118 else if ($c2 === -1)
119 {
120 $fill = str_repeat(':0', 7 - $c1);
121 $ip = str_replace('::', $fill, $ip);
122 }
123 // xxx::xxx
124 else
125 {
126 $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
127 $ip = str_replace('::', $fill, $ip);
128 }
129 }
130 return $ip;
131 }
132
133 /**
134 * Compresses an IPv6 address
135 *
136 * RFC 4291 allows you to compress concecutive zero pieces in an address to
137 * '::'. This method expects a valid IPv6 address and compresses consecutive
138 * zero pieces to '::'.
139 *
140 * Example: FF01:0:0:0:0:0:0:101 -> FF01::101
141 * 0:0:0:0:0:0:0:1 -> ::1
142 *
143 * @see uncompress()
144 * @param string $ip An IPv6 address
145 * @return string The compressed IPv6 address
146 */
147 public static function compress($ip)
148 {
149 // Prepare the IP to be compressed
150 $ip = self::uncompress($ip);
151 $ip_parts = self::split_v6_v4($ip);
152
153 // Replace all leading zeros
154 $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
155
156 // Find bunches of zeros
157 if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
158 {
159 $max = 0;
160 $pos = null;
161 foreach ($matches[0] as $match)
162 {
163 if (strlen($match[0]) > $max)
164 {
165 $max = strlen($match[0]);
166 $pos = $match[1];
167 }
168 }
169
170 $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
171 }
172
173 if ($ip_parts[1] !== '')
174 {
175 return implode(':', $ip_parts);
176 }
177 else
178 {
179 return $ip_parts[0];
180 }
181 }
182
183 /**
184 * Splits an IPv6 address into the IPv6 and IPv4 representation parts
185 *
186 * RFC 4291 allows you to represent the last two parts of an IPv6 address
187 * using the standard IPv4 representation
188 *
189 * Example: 0:0:0:0:0:0:13.1.68.3
190 * 0:0:0:0:0:FFFF:129.144.52.38
191 *
192 * @param string $ip An IPv6 address
193 * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
194 */
195 private static function split_v6_v4($ip)
196 {
197 if (strpos($ip, '.') !== false)
198 {
199 $pos = strrpos($ip, ':');
200 $ipv6_part = substr($ip, 0, $pos);
201 $ipv4_part = substr($ip, $pos + 1);
202 return array($ipv6_part, $ipv4_part);
203 }
204 else
205 {
206 return array($ip, '');
207 }
208 }
209
210 /**
211 * Checks an IPv6 address
212 *
213 * Checks if the given IP is a valid IPv6 address
214 *
215 * @param string $ip An IPv6 address
216 * @return bool true if $ip is a valid IPv6 address
217 */
218 public static function check_ipv6($ip)
219 {
220 $ip = self::uncompress($ip);
221 list($ipv6, $ipv4) = self::split_v6_v4($ip);
222 $ipv6 = explode(':', $ipv6);
223 $ipv4 = explode('.', $ipv4);
224 if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
225 {
226 foreach ($ipv6 as $ipv6_part)
227 {
228 // The section can't be empty
229 if ($ipv6_part === '')
230 return false;
231
232 // Nor can it be over four characters
233 if (strlen($ipv6_part) > 4)
234 return false;
235
236 // Remove leading zeros (this is safe because of the above)
237 $ipv6_part = ltrim($ipv6_part, '0');
238 if ($ipv6_part === '')
239 $ipv6_part = '0';
240
241 // Check the value is valid
242 $value = hexdec($ipv6_part);
243 if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
244 return false;
245 }
246 if (count($ipv4) === 4)
247 {
248 foreach ($ipv4 as $ipv4_part)
249 {
250 $value = (int) $ipv4_part;
251 if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
252 return false;
253 }
254 }
255 return true;
256 }
257 else
258 {
259 return false;
260 }
261 }
262
263 /**
264 * Checks if the given IP is a valid IPv6 address
265 *
266 * @codeCoverageIgnore
267 * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
268 * @see check_ipv6
269 * @param string $ip An IPv6 address
270 * @return bool true if $ip is a valid IPv6 address
271 */
272 public static function checkIPv6($ip)
273 {
274 return self::check_ipv6($ip);
275 }
276}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Parse/Date.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Parse/Date.php
new file mode 100644
index 00000000..d51f500d
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Parse/Date.php
@@ -0,0 +1,983 @@
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/**
47 * Date Parser
48 *
49 * @package SimplePie
50 * @subpackage Parsing
51 */
52class SimplePie_Parse_Date
53{
54 /**
55 * Input data
56 *
57 * @access protected
58 * @var string
59 */
60 var $date;
61
62 /**
63 * List of days, calendar day name => ordinal day number in the week
64 *
65 * @access protected
66 * @var array
67 */
68 var $day = array(
69 // English
70 'mon' => 1,
71 'monday' => 1,
72 'tue' => 2,
73 'tuesday' => 2,
74 'wed' => 3,
75 'wednesday' => 3,
76 'thu' => 4,
77 'thursday' => 4,
78 'fri' => 5,
79 'friday' => 5,
80 'sat' => 6,
81 'saturday' => 6,
82 'sun' => 7,
83 'sunday' => 7,
84 // Dutch
85 'maandag' => 1,
86 'dinsdag' => 2,
87 'woensdag' => 3,
88 'donderdag' => 4,
89 'vrijdag' => 5,
90 'zaterdag' => 6,
91 'zondag' => 7,
92 // French
93 'lundi' => 1,
94 'mardi' => 2,
95 'mercredi' => 3,
96 'jeudi' => 4,
97 'vendredi' => 5,
98 'samedi' => 6,
99 'dimanche' => 7,
100 // German
101 'montag' => 1,
102 'dienstag' => 2,
103 'mittwoch' => 3,
104 'donnerstag' => 4,
105 'freitag' => 5,
106 'samstag' => 6,
107 'sonnabend' => 6,
108 'sonntag' => 7,
109 // Italian
110 'lunedì' => 1,
111 'martedì' => 2,
112 'mercoledì' => 3,
113 'giovedì' => 4,
114 'venerdì' => 5,
115 'sabato' => 6,
116 'domenica' => 7,
117 // Spanish
118 'lunes' => 1,
119 'martes' => 2,
120 'miércoles' => 3,
121 'jueves' => 4,
122 'viernes' => 5,
123 'sábado' => 6,
124 'domingo' => 7,
125 // Finnish
126 'maanantai' => 1,
127 'tiistai' => 2,
128 'keskiviikko' => 3,
129 'torstai' => 4,
130 'perjantai' => 5,
131 'lauantai' => 6,
132 'sunnuntai' => 7,
133 // Hungarian
134 'hétfő' => 1,
135 'kedd' => 2,
136 'szerda' => 3,
137 'csütörtok' => 4,
138 'péntek' => 5,
139 'szombat' => 6,
140 'vasárnap' => 7,
141 // Greek
142 'Δευ' => 1,
143 'Τρι' => 2,
144 'Τετ' => 3,
145 'Πεμ' => 4,
146 'Παρ' => 5,
147 'Σαβ' => 6,
148 'Κυρ' => 7,
149 );
150
151 /**
152 * List of months, calendar month name => calendar month number
153 *
154 * @access protected
155 * @var array
156 */
157 var $month = array(
158 // English
159 'jan' => 1,
160 'january' => 1,
161 'feb' => 2,
162 'february' => 2,
163 'mar' => 3,
164 'march' => 3,
165 'apr' => 4,
166 'april' => 4,
167 'may' => 5,
168 // No long form of May
169 'jun' => 6,
170 'june' => 6,
171 'jul' => 7,
172 'july' => 7,
173 'aug' => 8,
174 'august' => 8,
175 'sep' => 9,
176 'september' => 8,
177 'oct' => 10,
178 'october' => 10,
179 'nov' => 11,
180 'november' => 11,
181 'dec' => 12,
182 'december' => 12,
183 // Dutch
184 'januari' => 1,
185 'februari' => 2,
186 'maart' => 3,
187 'april' => 4,
188 'mei' => 5,
189 'juni' => 6,
190 'juli' => 7,
191 'augustus' => 8,
192 'september' => 9,
193 'oktober' => 10,
194 'november' => 11,
195 'december' => 12,
196 // French
197 'janvier' => 1,
198 'février' => 2,
199 'mars' => 3,
200 'avril' => 4,
201 'mai' => 5,
202 'juin' => 6,
203 'juillet' => 7,
204 'août' => 8,
205 'septembre' => 9,
206 'octobre' => 10,
207 'novembre' => 11,
208 'décembre' => 12,
209 // German
210 'januar' => 1,
211 'februar' => 2,
212 'märz' => 3,
213 'april' => 4,
214 'mai' => 5,
215 'juni' => 6,
216 'juli' => 7,
217 'august' => 8,
218 'september' => 9,
219 'oktober' => 10,
220 'november' => 11,
221 'dezember' => 12,
222 // Italian
223 'gennaio' => 1,
224 'febbraio' => 2,
225 'marzo' => 3,
226 'aprile' => 4,
227 'maggio' => 5,
228 'giugno' => 6,
229 'luglio' => 7,
230 'agosto' => 8,
231 'settembre' => 9,
232 'ottobre' => 10,
233 'novembre' => 11,
234 'dicembre' => 12,
235 // Spanish
236 'enero' => 1,
237 'febrero' => 2,
238 'marzo' => 3,
239 'abril' => 4,
240 'mayo' => 5,
241 'junio' => 6,
242 'julio' => 7,
243 'agosto' => 8,
244 'septiembre' => 9,
245 'setiembre' => 9,
246 'octubre' => 10,
247 'noviembre' => 11,
248 'diciembre' => 12,
249 // Finnish
250 'tammikuu' => 1,
251 'helmikuu' => 2,
252 'maaliskuu' => 3,
253 'huhtikuu' => 4,
254 'toukokuu' => 5,
255 'kesäkuu' => 6,
256 'heinäkuu' => 7,
257 'elokuu' => 8,
258 'suuskuu' => 9,
259 'lokakuu' => 10,
260 'marras' => 11,
261 'joulukuu' => 12,
262 // Hungarian
263 'január' => 1,
264 'február' => 2,
265 'március' => 3,
266 'április' => 4,
267 'május' => 5,
268 'június' => 6,
269 'július' => 7,
270 'augusztus' => 8,
271 'szeptember' => 9,
272 'október' => 10,
273 'november' => 11,
274 'december' => 12,
275 // Greek
276 'Ιαν' => 1,
277 'Φεβ' => 2,
278 'Μάώ' => 3,
279 'Μαώ' => 3,
280 'Απρ' => 4,
281 'Μάι' => 5,
282 'Μαϊ' => 5,
283 'Μαι' => 5,
284 'Ιούν' => 6,
285 'Ιον' => 6,
286 'Ιούλ' => 7,
287 'Ιολ' => 7,
288 'Αύγ' => 8,
289 'Αυγ' => 8,
290 'Σεπ' => 9,
291 'Οκτ' => 10,
292 'Νοέ' => 11,
293 'Δεκ' => 12,
294 );
295
296 /**
297 * List of timezones, abbreviation => offset from UTC
298 *
299 * @access protected
300 * @var array
301 */
302 var $timezone = array(
303 'ACDT' => 37800,
304 'ACIT' => 28800,
305 'ACST' => 34200,
306 'ACT' => -18000,
307 'ACWDT' => 35100,
308 'ACWST' => 31500,
309 'AEDT' => 39600,
310 'AEST' => 36000,
311 'AFT' => 16200,
312 'AKDT' => -28800,
313 'AKST' => -32400,
314 'AMDT' => 18000,
315 'AMT' => -14400,
316 'ANAST' => 46800,
317 'ANAT' => 43200,
318 'ART' => -10800,
319 'AZOST' => -3600,
320 'AZST' => 18000,
321 'AZT' => 14400,
322 'BIOT' => 21600,
323 'BIT' => -43200,
324 'BOT' => -14400,
325 'BRST' => -7200,
326 'BRT' => -10800,
327 'BST' => 3600,
328 'BTT' => 21600,
329 'CAST' => 18000,
330 'CAT' => 7200,
331 'CCT' => 23400,
332 'CDT' => -18000,
333 'CEDT' => 7200,
334 'CET' => 3600,
335 'CGST' => -7200,
336 'CGT' => -10800,
337 'CHADT' => 49500,
338 'CHAST' => 45900,
339 'CIST' => -28800,
340 'CKT' => -36000,
341 'CLDT' => -10800,
342 'CLST' => -14400,
343 'COT' => -18000,
344 'CST' => -21600,
345 'CVT' => -3600,
346 'CXT' => 25200,
347 'DAVT' => 25200,
348 'DTAT' => 36000,
349 'EADT' => -18000,
350 'EAST' => -21600,
351 'EAT' => 10800,
352 'ECT' => -18000,
353 'EDT' => -14400,
354 'EEST' => 10800,
355 'EET' => 7200,
356 'EGT' => -3600,
357 'EKST' => 21600,
358 'EST' => -18000,
359 'FJT' => 43200,
360 'FKDT' => -10800,
361 'FKST' => -14400,
362 'FNT' => -7200,
363 'GALT' => -21600,
364 'GEDT' => 14400,
365 'GEST' => 10800,
366 'GFT' => -10800,
367 'GILT' => 43200,
368 'GIT' => -32400,
369 'GST' => 14400,
370 'GST' => -7200,
371 'GYT' => -14400,
372 'HAA' => -10800,
373 'HAC' => -18000,
374 'HADT' => -32400,
375 'HAE' => -14400,
376 'HAP' => -25200,
377 'HAR' => -21600,
378 'HAST' => -36000,
379 'HAT' => -9000,
380 'HAY' => -28800,
381 'HKST' => 28800,
382 'HMT' => 18000,
383 'HNA' => -14400,
384 'HNC' => -21600,
385 'HNE' => -18000,
386 'HNP' => -28800,
387 'HNR' => -25200,
388 'HNT' => -12600,
389 'HNY' => -32400,
390 'IRDT' => 16200,
391 'IRKST' => 32400,
392 'IRKT' => 28800,
393 'IRST' => 12600,
394 'JFDT' => -10800,
395 'JFST' => -14400,
396 'JST' => 32400,
397 'KGST' => 21600,
398 'KGT' => 18000,
399 'KOST' => 39600,
400 'KOVST' => 28800,
401 'KOVT' => 25200,
402 'KRAST' => 28800,
403 'KRAT' => 25200,
404 'KST' => 32400,
405 'LHDT' => 39600,
406 'LHST' => 37800,
407 'LINT' => 50400,
408 'LKT' => 21600,
409 'MAGST' => 43200,
410 'MAGT' => 39600,
411 'MAWT' => 21600,
412 'MDT' => -21600,
413 'MESZ' => 7200,
414 'MEZ' => 3600,
415 'MHT' => 43200,
416 'MIT' => -34200,
417 'MNST' => 32400,
418 'MSDT' => 14400,
419 'MSST' => 10800,
420 'MST' => -25200,
421 'MUT' => 14400,
422 'MVT' => 18000,
423 'MYT' => 28800,
424 'NCT' => 39600,
425 'NDT' => -9000,
426 'NFT' => 41400,
427 'NMIT' => 36000,
428 'NOVST' => 25200,
429 'NOVT' => 21600,
430 'NPT' => 20700,
431 'NRT' => 43200,
432 'NST' => -12600,
433 'NUT' => -39600,
434 'NZDT' => 46800,
435 'NZST' => 43200,
436 'OMSST' => 25200,
437 'OMST' => 21600,
438 'PDT' => -25200,
439 'PET' => -18000,
440 'PETST' => 46800,
441 'PETT' => 43200,
442 'PGT' => 36000,
443 'PHOT' => 46800,
444 'PHT' => 28800,
445 'PKT' => 18000,
446 'PMDT' => -7200,
447 'PMST' => -10800,
448 'PONT' => 39600,
449 'PST' => -28800,
450 'PWT' => 32400,
451 'PYST' => -10800,
452 'PYT' => -14400,
453 'RET' => 14400,
454 'ROTT' => -10800,
455 'SAMST' => 18000,
456 'SAMT' => 14400,
457 'SAST' => 7200,
458 'SBT' => 39600,
459 'SCDT' => 46800,
460 'SCST' => 43200,
461 'SCT' => 14400,
462 'SEST' => 3600,
463 'SGT' => 28800,
464 'SIT' => 28800,
465 'SRT' => -10800,
466 'SST' => -39600,
467 'SYST' => 10800,
468 'SYT' => 7200,
469 'TFT' => 18000,
470 'THAT' => -36000,
471 'TJT' => 18000,
472 'TKT' => -36000,
473 'TMT' => 18000,
474 'TOT' => 46800,
475 'TPT' => 32400,
476 'TRUT' => 36000,
477 'TVT' => 43200,
478 'TWT' => 28800,
479 'UYST' => -7200,
480 'UYT' => -10800,
481 'UZT' => 18000,
482 'VET' => -14400,
483 'VLAST' => 39600,
484 'VLAT' => 36000,
485 'VOST' => 21600,
486 'VUT' => 39600,
487 'WAST' => 7200,
488 'WAT' => 3600,
489 'WDT' => 32400,
490 'WEST' => 3600,
491 'WFT' => 43200,
492 'WIB' => 25200,
493 'WIT' => 32400,
494 'WITA' => 28800,
495 'WKST' => 18000,
496 'WST' => 28800,
497 'YAKST' => 36000,
498 'YAKT' => 32400,
499 'YAPT' => 36000,
500 'YEKST' => 21600,
501 'YEKT' => 18000,
502 );
503
504 /**
505 * Cached PCRE for SimplePie_Parse_Date::$day
506 *
507 * @access protected
508 * @var string
509 */
510 var $day_pcre;
511
512 /**
513 * Cached PCRE for SimplePie_Parse_Date::$month
514 *
515 * @access protected
516 * @var string
517 */
518 var $month_pcre;
519
520 /**
521 * Array of user-added callback methods
522 *
523 * @access private
524 * @var array
525 */
526 var $built_in = array();
527
528 /**
529 * Array of user-added callback methods
530 *
531 * @access private
532 * @var array
533 */
534 var $user = array();
535
536 /**
537 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
538 * self::month_pcre, and self::built_in
539 *
540 * @access private
541 */
542 public function __construct()
543 {
544 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
545 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
546
547 static $cache;
548 if (!isset($cache[get_class($this)]))
549 {
550 $all_methods = get_class_methods($this);
551
552 foreach ($all_methods as $method)
553 {
554 if (strtolower(substr($method, 0, 5)) === 'date_')
555 {
556 $cache[get_class($this)][] = $method;
557 }
558 }
559 }
560
561 foreach ($cache[get_class($this)] as $method)
562 {
563 $this->built_in[] = $method;
564 }
565 }
566
567 /**
568 * Get the object
569 *
570 * @access public
571 */
572 public static function get()
573 {
574 static $object;
575 if (!$object)
576 {
577 $object = new SimplePie_Parse_Date;
578 }
579 return $object;
580 }
581
582 /**
583 * Parse a date
584 *
585 * @final
586 * @access public
587 * @param string $date Date to parse
588 * @return int Timestamp corresponding to date string, or false on failure
589 */
590 public function parse($date)
591 {
592 foreach ($this->user as $method)
593 {
594 if (($returned = call_user_func($method, $date)) !== false)
595 {
596 return $returned;
597 }
598 }
599
600 foreach ($this->built_in as $method)
601 {
602 if (($returned = call_user_func(array($this, $method), $date)) !== false)
603 {
604 return $returned;
605 }
606 }
607
608 return false;
609 }
610
611 /**
612 * Add a callback method to parse a date
613 *
614 * @final
615 * @access public
616 * @param callback $callback
617 */
618 public function add_callback($callback)
619 {
620 if (is_callable($callback))
621 {
622 $this->user[] = $callback;
623 }
624 else
625 {
626 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
627 }
628 }
629
630 /**
631 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
632 * well as allowing any of upper or lower case "T", horizontal tabs, or
633 * spaces to be used as the time seperator (including more than one))
634 *
635 * @access protected
636 * @return int Timestamp
637 */
638 public function date_w3cdtf($date)
639 {
640 static $pcre;
641 if (!$pcre)
642 {
643 $year = '([0-9]{4})';
644 $month = $day = $hour = $minute = $second = '([0-9]{2})';
645 $decimal = '([0-9]*)';
646 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
647 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
648 }
649 if (preg_match($pcre, $date, $match))
650 {
651 /*
652 Capturing subpatterns:
653 1: Year
654 2: Month
655 3: Day
656 4: Hour
657 5: Minute
658 6: Second
659 7: Decimal fraction of a second
660 8: Zulu
661 9: Timezone ±
662 10: Timezone hours
663 11: Timezone minutes
664 */
665
666 // Fill in empty matches
667 for ($i = count($match); $i <= 3; $i++)
668 {
669 $match[$i] = '1';
670 }
671
672 for ($i = count($match); $i <= 7; $i++)
673 {
674 $match[$i] = '0';
675 }
676
677 // Numeric timezone
678 if (isset($match[9]) && $match[9] !== '')
679 {
680 $timezone = $match[10] * 3600;
681 $timezone += $match[11] * 60;
682 if ($match[9] === '-')
683 {
684 $timezone = 0 - $timezone;
685 }
686 }
687 else
688 {
689 $timezone = 0;
690 }
691
692 // Convert the number of seconds to an integer, taking decimals into account
693 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
694
695 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
696 }
697 else
698 {
699 return false;
700 }
701 }
702
703 /**
704 * Remove RFC822 comments
705 *
706 * @access protected
707 * @param string $data Data to strip comments from
708 * @return string Comment stripped string
709 */
710 public function remove_rfc2822_comments($string)
711 {
712 $string = (string) $string;
713 $position = 0;
714 $length = strlen($string);
715 $depth = 0;
716
717 $output = '';
718
719 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
720 {
721 $output .= substr($string, $position, $pos - $position);
722 $position = $pos + 1;
723 if ($string[$pos - 1] !== '\\')
724 {
725 $depth++;
726 while ($depth && $position < $length)
727 {
728 $position += strcspn($string, '()', $position);
729 if ($string[$position - 1] === '\\')
730 {
731 $position++;
732 continue;
733 }
734 elseif (isset($string[$position]))
735 {
736 switch ($string[$position])
737 {
738 case '(':
739 $depth++;
740 break;
741
742 case ')':
743 $depth--;
744 break;
745 }
746 $position++;
747 }
748 else
749 {
750 break;
751 }
752 }
753 }
754 else
755 {
756 $output .= '(';
757 }
758 }
759 $output .= substr($string, $position);
760
761 return $output;
762 }
763
764 /**
765 * Parse RFC2822's date format
766 *
767 * @access protected
768 * @return int Timestamp
769 */
770 public function date_rfc2822($date)
771 {
772 static $pcre;
773 if (!$pcre)
774 {
775 $wsp = '[\x09\x20]';
776 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
777 $optional_fws = $fws . '?';
778 $day_name = $this->day_pcre;
779 $month = $this->month_pcre;
780 $day = '([0-9]{1,2})';
781 $hour = $minute = $second = '([0-9]{2})';
782 $year = '([0-9]{2,4})';
783 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
784 $character_zone = '([A-Z]{1,5})';
785 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
786 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
787 }
788 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
789 {
790 /*
791 Capturing subpatterns:
792 1: Day name
793 2: Day
794 3: Month
795 4: Year
796 5: Hour
797 6: Minute
798 7: Second
799 8: Timezone ±
800 9: Timezone hours
801 10: Timezone minutes
802 11: Alphabetic timezone
803 */
804
805 // Find the month number
806 $month = $this->month[strtolower($match[3])];
807
808 // Numeric timezone
809 if ($match[8] !== '')
810 {
811 $timezone = $match[9] * 3600;
812 $timezone += $match[10] * 60;
813 if ($match[8] === '-')
814 {
815 $timezone = 0 - $timezone;
816 }
817 }
818 // Character timezone
819 elseif (isset($this->timezone[strtoupper($match[11])]))
820 {
821 $timezone = $this->timezone[strtoupper($match[11])];
822 }
823 // Assume everything else to be -0000
824 else
825 {
826 $timezone = 0;
827 }
828
829 // Deal with 2/3 digit years
830 if ($match[4] < 50)
831 {
832 $match[4] += 2000;
833 }
834 elseif ($match[4] < 1000)
835 {
836 $match[4] += 1900;
837 }
838
839 // Second is optional, if it is empty set it to zero
840 if ($match[7] !== '')
841 {
842 $second = $match[7];
843 }
844 else
845 {
846 $second = 0;
847 }
848
849 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
850 }
851 else
852 {
853 return false;
854 }
855 }
856
857 /**
858 * Parse RFC850's date format
859 *
860 * @access protected
861 * @return int Timestamp
862 */
863 public function date_rfc850($date)
864 {
865 static $pcre;
866 if (!$pcre)
867 {
868 $space = '[\x09\x20]+';
869 $day_name = $this->day_pcre;
870 $month = $this->month_pcre;
871 $day = '([0-9]{1,2})';
872 $year = $hour = $minute = $second = '([0-9]{2})';
873 $zone = '([A-Z]{1,5})';
874 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
875 }
876 if (preg_match($pcre, $date, $match))
877 {
878 /*
879 Capturing subpatterns:
880 1: Day name
881 2: Day
882 3: Month
883 4: Year
884 5: Hour
885 6: Minute
886 7: Second
887 8: Timezone
888 */
889
890 // Month
891 $month = $this->month[strtolower($match[3])];
892
893 // Character timezone
894 if (isset($this->timezone[strtoupper($match[8])]))
895 {
896 $timezone = $this->timezone[strtoupper($match[8])];
897 }
898 // Assume everything else to be -0000
899 else
900 {
901 $timezone = 0;
902 }
903
904 // Deal with 2 digit year
905 if ($match[4] < 50)
906 {
907 $match[4] += 2000;
908 }
909 else
910 {
911 $match[4] += 1900;
912 }
913
914 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
915 }
916 else
917 {
918 return false;
919 }
920 }
921
922 /**
923 * Parse C99's asctime()'s date format
924 *
925 * @access protected
926 * @return int Timestamp
927 */
928 public function date_asctime($date)
929 {
930 static $pcre;
931 if (!$pcre)
932 {
933 $space = '[\x09\x20]+';
934 $wday_name = $this->day_pcre;
935 $mon_name = $this->month_pcre;
936 $day = '([0-9]{1,2})';
937 $hour = $sec = $min = '([0-9]{2})';
938 $year = '([0-9]{4})';
939 $terminator = '\x0A?\x00?';
940 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
941 }
942 if (preg_match($pcre, $date, $match))
943 {
944 /*
945 Capturing subpatterns:
946 1: Day name
947 2: Month
948 3: Day
949 4: Hour
950 5: Minute
951 6: Second
952 7: Year
953 */
954
955 $month = $this->month[strtolower($match[2])];
956 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
957 }
958 else
959 {
960 return false;
961 }
962 }
963
964 /**
965 * Parse dates using strtotime()
966 *
967 * @access protected
968 * @return int Timestamp
969 */
970 public function date_strtotime($date)
971 {
972 $strtotime = strtotime($date);
973 if ($strtotime === -1 || $strtotime === false)
974 {
975 return false;
976 }
977 else
978 {
979 return $strtotime;
980 }
981 }
982}
983
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Parser.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Parser.php
new file mode 100644
index 00000000..d698552c
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Parser.php
@@ -0,0 +1,407 @@
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 * Parses XML into something sane
47 *
48 *
49 * This class can be overloaded with {@see SimplePie::set_parser_class()}
50 *
51 * @package SimplePie
52 * @subpackage Parsing
53 */
54class SimplePie_Parser
55{
56 var $error_code;
57 var $error_string;
58 var $current_line;
59 var $current_column;
60 var $current_byte;
61 var $separator = ' ';
62 var $namespace = array('');
63 var $element = array('');
64 var $xml_base = array('');
65 var $xml_base_explicit = array(false);
66 var $xml_lang = array('');
67 var $data = array();
68 var $datas = array(array());
69 var $current_xhtml_construct = -1;
70 var $encoding;
71 protected $registry;
72
73 public function set_registry(SimplePie_Registry $registry)
74 {
75 $this->registry = $registry;
76 }
77
78 public function parse(&$data, $encoding)
79 {
80 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
81 if (strtoupper($encoding) === 'US-ASCII')
82 {
83 $this->encoding = 'UTF-8';
84 }
85 else
86 {
87 $this->encoding = $encoding;
88 }
89
90 // Strip BOM:
91 // UTF-32 Big Endian BOM
92 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
93 {
94 $data = substr($data, 4);
95 }
96 // UTF-32 Little Endian BOM
97 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
98 {
99 $data = substr($data, 4);
100 }
101 // UTF-16 Big Endian BOM
102 elseif (substr($data, 0, 2) === "\xFE\xFF")
103 {
104 $data = substr($data, 2);
105 }
106 // UTF-16 Little Endian BOM
107 elseif (substr($data, 0, 2) === "\xFF\xFE")
108 {
109 $data = substr($data, 2);
110 }
111 // UTF-8 BOM
112 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
113 {
114 $data = substr($data, 3);
115 }
116
117 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
118 {
119 $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
120 if ($declaration->parse())
121 {
122 $data = substr($data, $pos + 2);
123 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
124 }
125 else
126 {
127 $this->error_string = 'SimplePie bug! Please report this!';
128 return false;
129 }
130 }
131
132 $return = true;
133
134 static $xml_is_sane = null;
135 if ($xml_is_sane === null)
136 {
137 $parser_check = xml_parser_create();
138 xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
139 xml_parser_free($parser_check);
140 $xml_is_sane = isset($values[0]['value']);
141 }
142
143 // Create the parser
144 if ($xml_is_sane)
145 {
146 $xml = xml_parser_create_ns($this->encoding, $this->separator);
147 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
148 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
149 xml_set_object($xml, $this);
150 xml_set_character_data_handler($xml, 'cdata');
151 xml_set_element_handler($xml, 'tag_open', 'tag_close');
152
153 // Parse!
154 if (!xml_parse($xml, $data, true))
155 {
156 $this->error_code = xml_get_error_code($xml);
157 $this->error_string = xml_error_string($this->error_code);
158 $return = false;
159 }
160 $this->current_line = xml_get_current_line_number($xml);
161 $this->current_column = xml_get_current_column_number($xml);
162 $this->current_byte = xml_get_current_byte_index($xml);
163 xml_parser_free($xml);
164 return $return;
165 }
166 else
167 {
168 libxml_clear_errors();
169 $xml = new XMLReader();
170 $xml->xml($data);
171 while (@$xml->read())
172 {
173 switch ($xml->nodeType)
174 {
175
176 case constant('XMLReader::END_ELEMENT'):
177 if ($xml->namespaceURI !== '')
178 {
179 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
180 }
181 else
182 {
183 $tagName = $xml->localName;
184 }
185 $this->tag_close(null, $tagName);
186 break;
187 case constant('XMLReader::ELEMENT'):
188 $empty = $xml->isEmptyElement;
189 if ($xml->namespaceURI !== '')
190 {
191 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
192 }
193 else
194 {
195 $tagName = $xml->localName;
196 }
197 $attributes = array();
198 while ($xml->moveToNextAttribute())
199 {
200 if ($xml->namespaceURI !== '')
201 {
202 $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
203 }
204 else
205 {
206 $attrName = $xml->localName;
207 }
208 $attributes[$attrName] = $xml->value;
209 }
210 $this->tag_open(null, $tagName, $attributes);
211 if ($empty)
212 {
213 $this->tag_close(null, $tagName);
214 }
215 break;
216 case constant('XMLReader::TEXT'):
217
218 case constant('XMLReader::CDATA'):
219 $this->cdata(null, $xml->value);
220 break;
221 }
222 }
223 if ($error = libxml_get_last_error())
224 {
225 $this->error_code = $error->code;
226 $this->error_string = $error->message;
227 $this->current_line = $error->line;
228 $this->current_column = $error->column;
229 return false;
230 }
231 else
232 {
233 return true;
234 }
235 }
236 }
237
238 public function get_error_code()
239 {
240 return $this->error_code;
241 }
242
243 public function get_error_string()
244 {
245 return $this->error_string;
246 }
247
248 public function get_current_line()
249 {
250 return $this->current_line;
251 }
252
253 public function get_current_column()
254 {
255 return $this->current_column;
256 }
257
258 public function get_current_byte()
259 {
260 return $this->current_byte;
261 }
262
263 public function get_data()
264 {
265 return $this->data;
266 }
267
268 public function tag_open($parser, $tag, $attributes)
269 {
270 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
271
272 $attribs = array();
273 foreach ($attributes as $name => $value)
274 {
275 list($attrib_namespace, $attribute) = $this->split_ns($name);
276 $attribs[$attrib_namespace][$attribute] = $value;
277 }
278
279 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
280 {
281 $base = $this->registry->call('Misc', 'absolutize_url', array($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)));
282 if ($base !== false)
283 {
284 $this->xml_base[] = $base;
285 $this->xml_base_explicit[] = true;
286 }
287 }
288 else
289 {
290 $this->xml_base[] = end($this->xml_base);
291 $this->xml_base_explicit[] = end($this->xml_base_explicit);
292 }
293
294 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
295 {
296 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
297 }
298 else
299 {
300 $this->xml_lang[] = end($this->xml_lang);
301 }
302
303 if ($this->current_xhtml_construct >= 0)
304 {
305 $this->current_xhtml_construct++;
306 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
307 {
308 $this->data['data'] .= '<' . end($this->element);
309 if (isset($attribs['']))
310 {
311 foreach ($attribs[''] as $name => $value)
312 {
313 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
314 }
315 }
316 $this->data['data'] .= '>';
317 }
318 }
319 else
320 {
321 $this->datas[] =& $this->data;
322 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
323 $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
324 if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
325 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
326 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_20 && in_array(end($this->element), array('title')))
327 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_090 && in_array(end($this->element), array('title')))
328 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_10 && in_array(end($this->element), array('title'))))
329 {
330 $this->current_xhtml_construct = 0;
331 }
332 }
333 }
334
335 public function cdata($parser, $cdata)
336 {
337 if ($this->current_xhtml_construct >= 0)
338 {
339 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
340 }
341 else
342 {
343 $this->data['data'] .= $cdata;
344 }
345 }
346
347 public function tag_close($parser, $tag)
348 {
349 if ($this->current_xhtml_construct >= 0)
350 {
351 $this->current_xhtml_construct--;
352 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
353 {
354 $this->data['data'] .= '</' . end($this->element) . '>';
355 }
356 }
357 if ($this->current_xhtml_construct === -1)
358 {
359 $this->data =& $this->datas[count($this->datas) - 1];
360 array_pop($this->datas);
361 }
362
363 array_pop($this->element);
364 array_pop($this->namespace);
365 array_pop($this->xml_base);
366 array_pop($this->xml_base_explicit);
367 array_pop($this->xml_lang);
368 }
369
370 public function split_ns($string)
371 {
372 static $cache = array();
373 if (!isset($cache[$string]))
374 {
375 if ($pos = strpos($string, $this->separator))
376 {
377 static $separator_length;
378 if (!$separator_length)
379 {
380 $separator_length = strlen($this->separator);
381 }
382 $namespace = substr($string, 0, $pos);
383 $local_name = substr($string, $pos + $separator_length);
384 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
385 {
386 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
387 }
388
389 // Normalize the Media RSS namespaces
390 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
391 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
392 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
393 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
394 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
395 {
396 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
397 }
398 $cache[$string] = array($namespace, $local_name);
399 }
400 else
401 {
402 $cache[$string] = array('', $string);
403 }
404 }
405 return $cache[$string];
406 }
407}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Rating.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Rating.php
new file mode 100644
index 00000000..8689e5df
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Rating.php
@@ -0,0 +1,129 @@
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 * Handles `<media:rating>` or `<itunes:explicit>` tags as defined in Media RSS and iTunes RSS respectively
47 *
48 * Used by {@see SimplePie_Enclosure::get_rating()} and {@see SimplePie_Enclosure::get_ratings()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_rating_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Rating
56{
57 /**
58 * Rating scheme
59 *
60 * @var string
61 * @see get_scheme()
62 */
63 var $scheme;
64
65 /**
66 * Rating value
67 *
68 * @var string
69 * @see get_value()
70 */
71 var $value;
72
73 /**
74 * Constructor, used to input the data
75 *
76 * For documentation on all the parameters, see the corresponding
77 * properties and their accessors
78 */
79 public function __construct($scheme = null, $value = null)
80 {
81 $this->scheme = $scheme;
82 $this->value = $value;
83 }
84
85 /**
86 * String-ified version
87 *
88 * @return string
89 */
90 public function __toString()
91 {
92 // There is no $this->data here
93 return md5(serialize($this));
94 }
95
96 /**
97 * Get the organizational scheme for the rating
98 *
99 * @return string|null
100 */
101 public function get_scheme()
102 {
103 if ($this->scheme !== null)
104 {
105 return $this->scheme;
106 }
107 else
108 {
109 return null;
110 }
111 }
112
113 /**
114 * Get the value of the rating
115 *
116 * @return string|null
117 */
118 public function get_value()
119 {
120 if ($this->value !== null)
121 {
122 return $this->value;
123 }
124 else
125 {
126 return null;
127 }
128 }
129}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Registry.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Registry.php
new file mode 100644
index 00000000..1072cdeb
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Registry.php
@@ -0,0 +1,225 @@
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 * Handles creating objects and calling methods
47 *
48 * Access this via {@see SimplePie::get_registry()}
49 *
50 * @package SimplePie
51 */
52class SimplePie_Registry
53{
54 /**
55 * Default class mapping
56 *
57 * Overriding classes *must* subclass these.
58 *
59 * @var array
60 */
61 protected $default = array(
62 'Cache' => 'SimplePie_Cache',
63 'Locator' => 'SimplePie_Locator',
64 'Parser' => 'SimplePie_Parser',
65 'File' => 'SimplePie_File',
66 'Sanitize' => 'SimplePie_Sanitize',
67 'Item' => 'SimplePie_Item',
68 'Author' => 'SimplePie_Author',
69 'Category' => 'SimplePie_Category',
70 'Enclosure' => 'SimplePie_Enclosure',
71 'Caption' => 'SimplePie_Caption',
72 'Copyright' => 'SimplePie_Copyright',
73 'Credit' => 'SimplePie_Credit',
74 'Rating' => 'SimplePie_Rating',
75 'Restriction' => 'SimplePie_Restriction',
76 'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
77 'Source' => 'SimplePie_Source',
78 'Misc' => 'SimplePie_Misc',
79 'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
80 'Parse_Date' => 'SimplePie_Parse_Date',
81 );
82
83 /**
84 * Class mapping
85 *
86 * @see register()
87 * @var array
88 */
89 protected $classes = array();
90
91 /**
92 * Legacy classes
93 *
94 * @see register()
95 * @var array
96 */
97 protected $legacy = array();
98
99 /**
100 * Constructor
101 *
102 * No-op
103 */
104 public function __construct() { }
105
106 /**
107 * Register a class
108 *
109 * @param string $type See {@see $default} for names
110 * @param string $class Class name, must subclass the corresponding default
111 * @param bool $legacy Whether to enable legacy support for this class
112 * @return bool Successfulness
113 */
114 public function register($type, $class, $legacy = false)
115 {
116 if (!is_subclass_of($class, $this->default[$type]))
117 {
118 return false;
119 }
120
121 $this->classes[$type] = $class;
122
123 if ($legacy)
124 {
125 $this->legacy[] = $class;
126 }
127
128 return true;
129 }
130
131 /**
132 * Get the class registered for a type
133 *
134 * Where possible, use {@see create()} or {@see call()} instead
135 *
136 * @param string $type
137 * @return string|null
138 */
139 public function get_class($type)
140 {
141 if (!empty($this->classes[$type]))
142 {
143 return $this->classes[$type];
144 }
145 if (!empty($this->default[$type]))
146 {
147 return $this->default[$type];
148 }
149
150 return null;
151 }
152
153 /**
154 * Create a new instance of a given type
155 *
156 * @param string $type
157 * @param array $parameters Parameters to pass to the constructor
158 * @return object Instance of class
159 */
160 public function &create($type, $parameters = array())
161 {
162 $class = $this->get_class($type);
163
164 if (in_array($class, $this->legacy))
165 {
166 switch ($type)
167 {
168 case 'locator':
169 // Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
170 // Specified: file, timeout, useragent, max_checked_feeds
171 $replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
172 array_splice($parameters, 3, 1, $replacement);
173 break;
174 }
175 }
176
177 if (!method_exists($class, '__construct'))
178 {
179 $instance = new $class;
180 }
181 else
182 {
183 $reflector = new ReflectionClass($class);
184 $instance = $reflector->newInstanceArgs($parameters);
185 }
186
187 if (method_exists($instance, 'set_registry'))
188 {
189 $instance->set_registry($this);
190 }
191 return $instance;
192 }
193
194 /**
195 * Call a static method for a type
196 *
197 * @param string $type
198 * @param string $method
199 * @param array $parameters
200 * @return mixed
201 */
202 public function &call($type, $method, $parameters = array())
203 {
204 $class = $this->get_class($type);
205
206 if (in_array($class, $this->legacy))
207 {
208 switch ($type)
209 {
210 case 'Cache':
211 // For backwards compatibility with old non-static
212 // Cache::create() methods
213 if ($method === 'get_handler')
214 {
215 $result = @call_user_func_array(array($class, 'create'), $parameters);
216 return $result;
217 }
218 break;
219 }
220 }
221
222 $result = call_user_func_array(array($class, $method), $parameters);
223 return $result;
224 }
225} \ No newline at end of file
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Restriction.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Restriction.php
new file mode 100644
index 00000000..4ba371bf
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Restriction.php
@@ -0,0 +1,155 @@
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 * Handles `<media:restriction>` as defined in Media RSS
47 *
48 * Used by {@see SimplePie_Enclosure::get_restriction()} and {@see SimplePie_Enclosure::get_restrictions()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_restriction_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Restriction
56{
57 /**
58 * Relationship ('allow'/'deny')
59 *
60 * @var string
61 * @see get_relationship()
62 */
63 var $relationship;
64
65 /**
66 * Type of restriction
67 *
68 * @var string
69 * @see get_type()
70 */
71 var $type;
72
73 /**
74 * Restricted values
75 *
76 * @var string
77 * @see get_value()
78 */
79 var $value;
80
81 /**
82 * Constructor, used to input the data
83 *
84 * For documentation on all the parameters, see the corresponding
85 * properties and their accessors
86 */
87 public function __construct($relationship = null, $type = null, $value = null)
88 {
89 $this->relationship = $relationship;
90 $this->type = $type;
91 $this->value = $value;
92 }
93
94 /**
95 * String-ified version
96 *
97 * @return string
98 */
99 public function __toString()
100 {
101 // There is no $this->data here
102 return md5(serialize($this));
103 }
104
105 /**
106 * Get the relationship
107 *
108 * @return string|null Either 'allow' or 'deny'
109 */
110 public function get_relationship()
111 {
112 if ($this->relationship !== null)
113 {
114 return $this->relationship;
115 }
116 else
117 {
118 return null;
119 }
120 }
121
122 /**
123 * Get the type
124 *
125 * @return string|null
126 */
127 public function get_type()
128 {
129 if ($this->type !== null)
130 {
131 return $this->type;
132 }
133 else
134 {
135 return null;
136 }
137 }
138
139 /**
140 * Get the list of restricted things
141 *
142 * @return string|null
143 */
144 public function get_value()
145 {
146 if ($this->value !== null)
147 {
148 return $this->value;
149 }
150 else
151 {
152 return null;
153 }
154 }
155}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Sanitize.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Sanitize.php
new file mode 100644
index 00000000..6810cc49
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Sanitize.php
@@ -0,0 +1,549 @@
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 data cleanup and post-processing
47 *
48 *
49 * This class can be overloaded with {@see SimplePie::set_sanitize_class()}
50 *
51 * @package SimplePie
52 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
53 */
54class SimplePie_Sanitize
55{
56 // Private vars
57 var $base;
58
59 // Options
60 var $remove_div = true;
61 var $image_handler = '';
62 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
63 var $encode_instead_of_strip = false;
64 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
65 var $strip_comments = false;
66 var $output_encoding = 'UTF-8';
67 var $enable_cache = true;
68 var $cache_location = './cache';
69 var $cache_name_function = 'md5';
70 var $timeout = 10;
71 var $useragent = '';
72 var $force_fsockopen = false;
73 var $replace_url_attributes = null;
74
75 public function __construct()
76 {
77 // Set defaults
78 $this->set_url_replacements(null);
79 }
80
81 public function remove_div($enable = true)
82 {
83 $this->remove_div = (bool) $enable;
84 }
85
86 public function set_image_handler($page = false)
87 {
88 if ($page)
89 {
90 $this->image_handler = (string) $page;
91 }
92 else
93 {
94 $this->image_handler = false;
95 }
96 }
97
98 public function set_registry(SimplePie_Registry $registry)
99 {
100 $this->registry = $registry;
101 }
102
103 public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
104 {
105 if (isset($enable_cache))
106 {
107 $this->enable_cache = (bool) $enable_cache;
108 }
109
110 if ($cache_location)
111 {
112 $this->cache_location = (string) $cache_location;
113 }
114
115 if ($cache_name_function)
116 {
117 $this->cache_name_function = (string) $cache_name_function;
118 }
119 }
120
121 public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
122 {
123 if ($timeout)
124 {
125 $this->timeout = (string) $timeout;
126 }
127
128 if ($useragent)
129 {
130 $this->useragent = (string) $useragent;
131 }
132
133 if ($force_fsockopen)
134 {
135 $this->force_fsockopen = (string) $force_fsockopen;
136 }
137 }
138
139 public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
140 {
141 if ($tags)
142 {
143 if (is_array($tags))
144 {
145 $this->strip_htmltags = $tags;
146 }
147 else
148 {
149 $this->strip_htmltags = explode(',', $tags);
150 }
151 }
152 else
153 {
154 $this->strip_htmltags = false;
155 }
156 }
157
158 public function encode_instead_of_strip($encode = false)
159 {
160 $this->encode_instead_of_strip = (bool) $encode;
161 }
162
163 public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
164 {
165 if ($attribs)
166 {
167 if (is_array($attribs))
168 {
169 $this->strip_attributes = $attribs;
170 }
171 else
172 {
173 $this->strip_attributes = explode(',', $attribs);
174 }
175 }
176 else
177 {
178 $this->strip_attributes = false;
179 }
180 }
181
182 public function strip_comments($strip = false)
183 {
184 $this->strip_comments = (bool) $strip;
185 }
186
187 public function set_output_encoding($encoding = 'UTF-8')
188 {
189 $this->output_encoding = (string) $encoding;
190 }
191
192 /**
193 * Set element/attribute key/value pairs of HTML attributes
194 * containing URLs that need to be resolved relative to the feed
195 *
196 * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
197 * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
198 * |q|@cite
199 *
200 * @since 1.0
201 * @param array|null $element_attribute Element/attribute key/value pairs, null for default
202 */
203 public function set_url_replacements($element_attribute = null)
204 {
205 if ($element_attribute === null)
206 {
207 $element_attribute = array(
208 'a' => 'href',
209 'area' => 'href',
210 'blockquote' => 'cite',
211 'del' => 'cite',
212 'form' => 'action',
213 'img' => array(
214 'longdesc',
215 'src'
216 ),
217 'input' => 'src',
218 'ins' => 'cite',
219 'q' => 'cite'
220 );
221 }
222 $this->replace_url_attributes = (array) $element_attribute;
223 }
224
225 public function sanitize($data, $type, $base = '')
226 {
227 $data = trim($data);
228 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
229 {
230 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
231 {
232 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
233 {
234 $type |= SIMPLEPIE_CONSTRUCT_HTML;
235 }
236 else
237 {
238 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
239 }
240 }
241
242 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
243 {
244 $data = base64_decode($data);
245 }
246
247 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
248 {
249
250 $document = new DOMDocument();
251 $document->encoding = 'UTF-8';
252 $data = $this->preprocess($data, $type);
253
254 set_error_handler(array('SimplePie_Misc', 'silence_errors'));
255 $document->loadHTML($data);
256 restore_error_handler();
257
258 // Strip comments
259 if ($this->strip_comments)
260 {
261 $xpath = new DOMXPath($document);
262 $comments = $xpath->query('//comment()');
263
264 foreach ($comments as $comment)
265 {
266 $comment->parentNode->removeChild($comment);
267 }
268 }
269
270 // Strip out HTML tags and attributes that might cause various security problems.
271 // Based on recommendations by Mark Pilgrim at:
272 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
273 if ($this->strip_htmltags)
274 {
275 foreach ($this->strip_htmltags as $tag)
276 {
277 $this->strip_tag($tag, $document, $type);
278 }
279 }
280
281 if ($this->strip_attributes)
282 {
283 foreach ($this->strip_attributes as $attrib)
284 {
285 $this->strip_attr($attrib, $document);
286 }
287 }
288
289 // Replace relative URLs
290 $this->base = $base;
291 foreach ($this->replace_url_attributes as $element => $attributes)
292 {
293 $this->replace_urls($document, $element, $attributes);
294 }
295
296 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
297 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
298 {
299 $images = $document->getElementsByTagName('img');
300 foreach ($images as $img)
301 {
302 if ($img->hasAttribute('src'))
303 {
304 $image_url = call_user_func($this->cache_name_function, $img->getAttribute('src'));
305 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, $image_url, 'spi'));
306
307 if ($cache->load())
308 {
309 $img->setAttribute('src', $this->image_handler . $image_url);
310 }
311 else
312 {
313 $file = $this->registry->create('File', array($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen));
314 $headers = $file->headers;
315
316 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
317 {
318 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
319 {
320 $img->setAttribute('src', $this->image_handler . $image_url);
321 }
322 else
323 {
324 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
325 }
326 }
327 }
328 }
329 }
330 }
331
332 // Remove the DOCTYPE
333 // Seems to cause segfaulting if we don't do this
334 if ($document->firstChild instanceof DOMDocumentType)
335 {
336 $document->removeChild($document->firstChild);
337 }
338
339 // Move everything from the body to the root
340 $real_body = $document->getElementsByTagName('body')->item(0)->childNodes->item(0);
341 $document->replaceChild($real_body, $document->firstChild);
342
343 // Finally, convert to a HTML string
344 $data = trim($document->saveHTML());
345
346 if ($this->remove_div)
347 {
348 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
349 $data = preg_replace('/<\/div>$/', '', $data);
350 }
351 else
352 {
353 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
354 }
355 }
356
357 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
358 {
359 $absolute = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
360 if ($absolute !== false)
361 {
362 $data = $absolute;
363 }
364 }
365
366 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
367 {
368 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
369 }
370
371 if ($this->output_encoding !== 'UTF-8')
372 {
373 $data = $this->registry->call('Misc', 'change_encoding', array($data, 'UTF-8', $this->output_encoding));
374 }
375 }
376 return $data;
377 }
378
379 protected function preprocess($html, $type)
380 {
381 $ret = '';
382 if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML)
383 {
384 // Atom XHTML constructs are wrapped with a div by default
385 // Note: No protection if $html contains a stray </div>!
386 $html = '<div>' . $html . '</div>';
387 $ret .= '<!DOCTYPE html>';
388 $content_type = 'text/html';
389 }
390 else
391 {
392 $ret .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
393 $content_type = 'application/xhtml+xml';
394 }
395
396 $ret .= '<html><head>';
397 $ret .= '<meta http-equiv="Content-Type" content="' . $content_type . '; charset=utf-8" />';
398 $ret .= '</head><body>' . $html . '</body></html>';
399 return $ret;
400 }
401
402 public function replace_urls($document, $tag, $attributes)
403 {
404 if (!is_array($attributes))
405 {
406 $attributes = array($attributes);
407 }
408
409 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
410 {
411 $elements = $document->getElementsByTagName($tag);
412 foreach ($elements as $element)
413 {
414 foreach ($attributes as $attribute)
415 {
416 if ($element->hasAttribute($attribute))
417 {
418 $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base));
419 if ($value !== false)
420 {
421 $element->setAttribute($attribute, $value);
422 }
423 }
424 }
425 }
426 }
427 }
428
429 public function do_strip_htmltags($match)
430 {
431 if ($this->encode_instead_of_strip)
432 {
433 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
434 {
435 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
436 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
437 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
438 }
439 else
440 {
441 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
442 }
443 }
444 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
445 {
446 return $match[4];
447 }
448 else
449 {
450 return '';
451 }
452 }
453
454 protected function strip_tag($tag, $document, $type)
455 {
456 $xpath = new DOMXPath($document);
457 $elements = $xpath->query('body//' . $tag);
458 if ($this->encode_instead_of_strip)
459 {
460 foreach ($elements as $element)
461 {
462 $fragment = $document->createDocumentFragment();
463
464 // For elements which aren't script or style, include the tag itself
465 if (!in_array($tag, array('script', 'style')))
466 {
467 $text = '<' . $tag;
468 if ($element->hasAttributes())
469 {
470 $attrs = array();
471 foreach ($element->attributes as $name => $attr)
472 {
473 $value = $attr->value;
474
475 // In XHTML, empty values should never exist, so we repeat the value
476 if (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_XHTML))
477 {
478 $value = $name;
479 }
480 // For HTML, empty is fine
481 elseif (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_HTML))
482 {
483 $attrs[] = $name;
484 continue;
485 }
486
487 // Standard attribute text
488 $attrs[] = $name . '="' . $attr->value . '"';
489 }
490 $text .= ' ' . implode(' ', $attrs);
491 }
492 $text .= '>';
493 $fragment->appendChild(new DOMText($text));
494 }
495
496 $number = $element->childNodes->length;
497 for ($i = $number; $i > 0; $i--)
498 {
499 $child = $element->childNodes->item(0);
500 $fragment->appendChild($child);
501 }
502
503 if (!in_array($tag, array('script', 'style')))
504 {
505 $fragment->appendChild(new DOMText('</' . $tag . '>'));
506 }
507
508 $element->parentNode->replaceChild($fragment, $element);
509 }
510
511 return;
512 }
513 elseif (in_array($tag, array('script', 'style')))
514 {
515 foreach ($elements as $element)
516 {
517 $element->parentNode->removeChild($element);
518 }
519
520 return;
521 }
522 else
523 {
524 foreach ($elements as $element)
525 {
526 $fragment = $document->createDocumentFragment();
527 $number = $element->childNodes->length;
528 for ($i = $number; $i > 0; $i--)
529 {
530 $child = $element->childNodes->item(0);
531 $fragment->appendChild($child);
532 }
533
534 $element->parentNode->replaceChild($fragment, $element);
535 }
536 }
537 }
538
539 protected function strip_attr($attrib, $document)
540 {
541 $xpath = new DOMXPath($document);
542 $elements = $xpath->query('//*[@' . $attrib . ']');
543
544 foreach ($elements as $element)
545 {
546 $element->removeAttribute($attrib);
547 }
548 }
549}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/Source.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/Source.php
new file mode 100644
index 00000000..51d8e6c2
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/Source.php
@@ -0,0 +1,611 @@
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 * Handles `<atom:source>`
47 *
48 * Used by {@see SimplePie_Item::get_source()}
49 *
50 * This class can be overloaded with {@see SimplePie::set_source_class()}
51 *
52 * @package SimplePie
53 * @subpackage API
54 */
55class SimplePie_Source
56{
57 var $item;
58 var $data = array();
59 protected $registry;
60
61 public function __construct($item, $data)
62 {
63 $this->item = $item;
64 $this->data = $data;
65 }
66
67 public function set_registry(SimplePie_Registry $registry)
68 {
69 $this->registry = $registry;
70 }
71
72 public function __toString()
73 {
74 return md5(serialize($this->data));
75 }
76
77 public function get_source_tags($namespace, $tag)
78 {
79 if (isset($this->data['child'][$namespace][$tag]))
80 {
81 return $this->data['child'][$namespace][$tag];
82 }
83 else
84 {
85 return null;
86 }
87 }
88
89 public function get_base($element = array())
90 {
91 return $this->item->get_base($element);
92 }
93
94 public function sanitize($data, $type, $base = '')
95 {
96 return $this->item->sanitize($data, $type, $base);
97 }
98
99 public function get_item()
100 {
101 return $this->item;
102 }
103
104 public function get_title()
105 {
106 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
107 {
108 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
109 }
110 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
111 {
112 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
113 }
114 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
115 {
116 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
117 }
118 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
119 {
120 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
121 }
122 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
123 {
124 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
125 }
126 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
127 {
128 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
129 }
130 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
131 {
132 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
133 }
134 else
135 {
136 return null;
137 }
138 }
139
140 public function get_category($key = 0)
141 {
142 $categories = $this->get_categories();
143 if (isset($categories[$key]))
144 {
145 return $categories[$key];
146 }
147 else
148 {
149 return null;
150 }
151 }
152
153 public function get_categories()
154 {
155 $categories = array();
156
157 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
158 {
159 $term = null;
160 $scheme = null;
161 $label = null;
162 if (isset($category['attribs']['']['term']))
163 {
164 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
165 }
166 if (isset($category['attribs']['']['scheme']))
167 {
168 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
169 }
170 if (isset($category['attribs']['']['label']))
171 {
172 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
173 }
174 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
175 }
176 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
177 {
178 // This is really the label, but keep this as the term also for BC.
179 // Label will also work on retrieving because that falls back to term.
180 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
181 if (isset($category['attribs']['']['domain']))
182 {
183 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
184 }
185 else
186 {
187 $scheme = null;
188 }
189 $categories[] = $this->registry->create('Category', array($term, $scheme, null));
190 }
191 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
192 {
193 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
194 }
195 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
196 {
197 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
198 }
199
200 if (!empty($categories))
201 {
202 return array_unique($categories);
203 }
204 else
205 {
206 return null;
207 }
208 }
209
210 public function get_author($key = 0)
211 {
212 $authors = $this->get_authors();
213 if (isset($authors[$key]))
214 {
215 return $authors[$key];
216 }
217 else
218 {
219 return null;
220 }
221 }
222
223 public function get_authors()
224 {
225 $authors = array();
226 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
227 {
228 $name = null;
229 $uri = null;
230 $email = null;
231 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
232 {
233 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
234 }
235 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
236 {
237 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
238 }
239 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
240 {
241 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
242 }
243 if ($name !== null || $email !== null || $uri !== null)
244 {
245 $authors[] = $this->registry->create('Author', array($name, $uri, $email));
246 }
247 }
248 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
249 {
250 $name = null;
251 $url = null;
252 $email = null;
253 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
254 {
255 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
256 }
257 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
258 {
259 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
260 }
261 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
262 {
263 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
264 }
265 if ($name !== null || $email !== null || $url !== null)
266 {
267 $authors[] = $this->registry->create('Author', array($name, $url, $email));
268 }
269 }
270 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
271 {
272 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
273 }
274 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
275 {
276 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
277 }
278 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
279 {
280 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
281 }
282
283 if (!empty($authors))
284 {
285 return array_unique($authors);
286 }
287 else
288 {
289 return null;
290 }
291 }
292
293 public function get_contributor($key = 0)
294 {
295 $contributors = $this->get_contributors();
296 if (isset($contributors[$key]))
297 {
298 return $contributors[$key];
299 }
300 else
301 {
302 return null;
303 }
304 }
305
306 public function get_contributors()
307 {
308 $contributors = array();
309 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
310 {
311 $name = null;
312 $uri = null;
313 $email = null;
314 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
315 {
316 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
317 }
318 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
319 {
320 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
321 }
322 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
323 {
324 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
325 }
326 if ($name !== null || $email !== null || $uri !== null)
327 {
328 $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
329 }
330 }
331 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
332 {
333 $name = null;
334 $url = null;
335 $email = null;
336 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
337 {
338 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
339 }
340 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
341 {
342 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
343 }
344 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
345 {
346 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
347 }
348 if ($name !== null || $email !== null || $url !== null)
349 {
350 $contributors[] = $this->registry->create('Author', array($name, $url, $email));
351 }
352 }
353
354 if (!empty($contributors))
355 {
356 return array_unique($contributors);
357 }
358 else
359 {
360 return null;
361 }
362 }
363
364 public function get_link($key = 0, $rel = 'alternate')
365 {
366 $links = $this->get_links($rel);
367 if (isset($links[$key]))
368 {
369 return $links[$key];
370 }
371 else
372 {
373 return null;
374 }
375 }
376
377 /**
378 * Added for parity between the parent-level and the item/entry-level.
379 */
380 public function get_permalink()
381 {
382 return $this->get_link(0);
383 }
384
385 public function get_links($rel = 'alternate')
386 {
387 if (!isset($this->data['links']))
388 {
389 $this->data['links'] = array();
390 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
391 {
392 foreach ($links as $link)
393 {
394 if (isset($link['attribs']['']['href']))
395 {
396 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
397 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
398 }
399 }
400 }
401 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
402 {
403 foreach ($links as $link)
404 {
405 if (isset($link['attribs']['']['href']))
406 {
407 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
408 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
409
410 }
411 }
412 }
413 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
414 {
415 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
416 }
417 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
418 {
419 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
420 }
421 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
422 {
423 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
424 }
425
426 $keys = array_keys($this->data['links']);
427 foreach ($keys as $key)
428 {
429 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
430 {
431 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
432 {
433 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
434 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
435 }
436 else
437 {
438 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
439 }
440 }
441 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
442 {
443 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
444 }
445 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
446 }
447 }
448
449 if (isset($this->data['links'][$rel]))
450 {
451 return $this->data['links'][$rel];
452 }
453 else
454 {
455 return null;
456 }
457 }
458
459 public function get_description()
460 {
461 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
462 {
463 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
464 }
465 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
466 {
467 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
468 }
469 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
470 {
471 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
472 }
473 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
474 {
475 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
476 }
477 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
478 {
479 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
480 }
481 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
482 {
483 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
484 }
485 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
486 {
487 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
488 }
489 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
490 {
491 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
492 }
493 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
494 {
495 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
496 }
497 else
498 {
499 return null;
500 }
501 }
502
503 public function get_copyright()
504 {
505 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
506 {
507 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
508 }
509 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
510 {
511 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
512 }
513 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
514 {
515 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
516 }
517 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
518 {
519 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
520 }
521 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
522 {
523 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
524 }
525 else
526 {
527 return null;
528 }
529 }
530
531 public function get_language()
532 {
533 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
534 {
535 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
536 }
537 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
538 {
539 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
540 }
541 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
542 {
543 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
544 }
545 elseif (isset($this->data['xml_lang']))
546 {
547 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
548 }
549 else
550 {
551 return null;
552 }
553 }
554
555 public function get_latitude()
556 {
557 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
558 {
559 return (float) $return[0]['data'];
560 }
561 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
562 {
563 return (float) $match[1];
564 }
565 else
566 {
567 return null;
568 }
569 }
570
571 public function get_longitude()
572 {
573 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
574 {
575 return (float) $return[0]['data'];
576 }
577 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
578 {
579 return (float) $return[0]['data'];
580 }
581 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
582 {
583 return (float) $match[2];
584 }
585 else
586 {
587 return null;
588 }
589 }
590
591 public function get_image_url()
592 {
593 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
594 {
595 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
596 }
597 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
598 {
599 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
600 }
601 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
602 {
603 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
604 }
605 else
606 {
607 return null;
608 }
609 }
610}
611
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php
new file mode 100644
index 00000000..aec19f10
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php
@@ -0,0 +1,362 @@
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/**
47 * Parses the XML Declaration
48 *
49 * @package SimplePie
50 * @subpackage Parsing
51 */
52class SimplePie_XML_Declaration_Parser
53{
54 /**
55 * XML Version
56 *
57 * @access public
58 * @var string
59 */
60 var $version = '1.0';
61
62 /**
63 * Encoding
64 *
65 * @access public
66 * @var string
67 */
68 var $encoding = 'UTF-8';
69
70 /**
71 * Standalone
72 *
73 * @access public
74 * @var bool
75 */
76 var $standalone = false;
77
78 /**
79 * Current state of the state machine
80 *
81 * @access private
82 * @var string
83 */
84 var $state = 'before_version_name';
85
86 /**
87 * Input data
88 *
89 * @access private
90 * @var string
91 */
92 var $data = '';
93
94 /**
95 * Input data length (to avoid calling strlen() everytime this is needed)
96 *
97 * @access private
98 * @var int
99 */
100 var $data_length = 0;
101
102 /**
103 * Current position of the pointer
104 *
105 * @var int
106 * @access private
107 */
108 var $position = 0;
109
110 /**
111 * Create an instance of the class with the input data
112 *
113 * @access public
114 * @param string $data Input data
115 */
116 public function __construct($data)
117 {
118 $this->data = $data;
119 $this->data_length = strlen($this->data);
120 }
121
122 /**
123 * Parse the input data
124 *
125 * @access public
126 * @return bool true on success, false on failure
127 */
128 public function parse()
129 {
130 while ($this->state && $this->state !== 'emit' && $this->has_data())
131 {
132 $state = $this->state;
133 $this->$state();
134 }
135 $this->data = '';
136 if ($this->state === 'emit')
137 {
138 return true;
139 }
140 else
141 {
142 $this->version = '';
143 $this->encoding = '';
144 $this->standalone = '';
145 return false;
146 }
147 }
148
149 /**
150 * Check whether there is data beyond the pointer
151 *
152 * @access private
153 * @return bool true if there is further data, false if not
154 */
155 public function has_data()
156 {
157 return (bool) ($this->position < $this->data_length);
158 }
159
160 /**
161 * Advance past any whitespace
162 *
163 * @return int Number of whitespace characters passed
164 */
165 public function skip_whitespace()
166 {
167 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
168 $this->position += $whitespace;
169 return $whitespace;
170 }
171
172 /**
173 * Read value
174 */
175 public function get_value()
176 {
177 $quote = substr($this->data, $this->position, 1);
178 if ($quote === '"' || $quote === "'")
179 {
180 $this->position++;
181 $len = strcspn($this->data, $quote, $this->position);
182 if ($this->has_data())
183 {
184 $value = substr($this->data, $this->position, $len);
185 $this->position += $len + 1;
186 return $value;
187 }
188 }
189 return false;
190 }
191
192 public function before_version_name()
193 {
194 if ($this->skip_whitespace())
195 {
196 $this->state = 'version_name';
197 }
198 else
199 {
200 $this->state = false;
201 }
202 }
203
204 public function version_name()
205 {
206 if (substr($this->data, $this->position, 7) === 'version')
207 {
208 $this->position += 7;
209 $this->skip_whitespace();
210 $this->state = 'version_equals';
211 }
212 else
213 {
214 $this->state = false;
215 }
216 }
217
218 public function version_equals()
219 {
220 if (substr($this->data, $this->position, 1) === '=')
221 {
222 $this->position++;
223 $this->skip_whitespace();
224 $this->state = 'version_value';
225 }
226 else
227 {
228 $this->state = false;
229 }
230 }
231
232 public function version_value()
233 {
234 if ($this->version = $this->get_value())
235 {
236 $this->skip_whitespace();
237 if ($this->has_data())
238 {
239 $this->state = 'encoding_name';
240 }
241 else
242 {
243 $this->state = 'emit';
244 }
245 }
246 else
247 {
248 $this->state = false;
249 }
250 }
251
252 public function encoding_name()
253 {
254 if (substr($this->data, $this->position, 8) === 'encoding')
255 {
256 $this->position += 8;
257 $this->skip_whitespace();
258 $this->state = 'encoding_equals';
259 }
260 else
261 {
262 $this->state = 'standalone_name';
263 }
264 }
265
266 public function encoding_equals()
267 {
268 if (substr($this->data, $this->position, 1) === '=')
269 {
270 $this->position++;
271 $this->skip_whitespace();
272 $this->state = 'encoding_value';
273 }
274 else
275 {
276 $this->state = false;
277 }
278 }
279
280 public function encoding_value()
281 {
282 if ($this->encoding = $this->get_value())
283 {
284 $this->skip_whitespace();
285 if ($this->has_data())
286 {
287 $this->state = 'standalone_name';
288 }
289 else
290 {
291 $this->state = 'emit';
292 }
293 }
294 else
295 {
296 $this->state = false;
297 }
298 }
299
300 public function standalone_name()
301 {
302 if (substr($this->data, $this->position, 10) === 'standalone')
303 {
304 $this->position += 10;
305 $this->skip_whitespace();
306 $this->state = 'standalone_equals';
307 }
308 else
309 {
310 $this->state = false;
311 }
312 }
313
314 public function standalone_equals()
315 {
316 if (substr($this->data, $this->position, 1) === '=')
317 {
318 $this->position++;
319 $this->skip_whitespace();
320 $this->state = 'standalone_value';
321 }
322 else
323 {
324 $this->state = false;
325 }
326 }
327
328 public function standalone_value()
329 {
330 if ($standalone = $this->get_value())
331 {
332 switch ($standalone)
333 {
334 case 'yes':
335 $this->standalone = true;
336 break;
337
338 case 'no':
339 $this->standalone = false;
340 break;
341
342 default:
343 $this->state = false;
344 return;
345 }
346
347 $this->skip_whitespace();
348 if ($this->has_data())
349 {
350 $this->state = false;
351 }
352 else
353 {
354 $this->state = 'emit';
355 }
356 }
357 else
358 {
359 $this->state = false;
360 }
361 }
362}
diff --git a/inc/3rdparty/libraries/simplepie/library/SimplePie/gzdecode.php b/inc/3rdparty/libraries/simplepie/library/SimplePie/gzdecode.php
new file mode 100644
index 00000000..52e024ea
--- /dev/null
+++ b/inc/3rdparty/libraries/simplepie/library/SimplePie/gzdecode.php
@@ -0,0 +1,371 @@
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/**
47 * Decode 'gzip' encoded HTTP data
48 *
49 * @package SimplePie
50 * @subpackage HTTP
51 * @link http://www.gzip.org/format.txt
52 */
53class SimplePie_gzdecode
54{
55 /**
56 * Compressed data
57 *
58 * @access private
59 * @var string
60 * @see gzdecode::$data
61 */
62 var $compressed_data;
63
64 /**
65 * Size of compressed data
66 *
67 * @access private
68 * @var int
69 */
70 var $compressed_size;
71
72 /**
73 * Minimum size of a valid gzip string
74 *
75 * @access private
76 * @var int
77 */
78 var $min_compressed_size = 18;
79
80 /**
81 * Current position of pointer
82 *
83 * @access private
84 * @var int
85 */
86 var $position = 0;
87
88 /**
89 * Flags (FLG)
90 *
91 * @access private
92 * @var int
93 */
94 var $flags;
95
96 /**
97 * Uncompressed data
98 *
99 * @access public
100 * @see gzdecode::$compressed_data
101 * @var string
102 */
103 var $data;
104
105 /**
106 * Modified time
107 *
108 * @access public
109 * @var int
110 */
111 var $MTIME;
112
113 /**
114 * Extra Flags
115 *
116 * @access public
117 * @var int
118 */
119 var $XFL;
120
121 /**
122 * Operating System
123 *
124 * @access public
125 * @var int
126 */
127 var $OS;
128
129 /**
130 * Subfield ID 1
131 *
132 * @access public
133 * @see gzdecode::$extra_field
134 * @see gzdecode::$SI2
135 * @var string
136 */
137 var $SI1;
138
139 /**
140 * Subfield ID 2
141 *
142 * @access public
143 * @see gzdecode::$extra_field
144 * @see gzdecode::$SI1
145 * @var string
146 */
147 var $SI2;
148
149 /**
150 * Extra field content
151 *
152 * @access public
153 * @see gzdecode::$SI1
154 * @see gzdecode::$SI2
155 * @var string
156 */
157 var $extra_field;
158
159 /**
160 * Original filename
161 *
162 * @access public
163 * @var string
164 */
165 var $filename;
166
167 /**
168 * Human readable comment
169 *
170 * @access public
171 * @var string
172 */
173 var $comment;
174
175 /**
176 * Don't allow anything to be set
177 *
178 * @param string $name
179 * @param mixed $value
180 */
181 public function __set($name, $value)
182 {
183 trigger_error("Cannot write property $name", E_USER_ERROR);
184 }
185
186 /**
187 * Set the compressed string and related properties
188 *
189 * @param string $data
190 */
191 public function __construct($data)
192 {
193 $this->compressed_data = $data;
194 $this->compressed_size = strlen($data);
195 }
196
197 /**
198 * Decode the GZIP stream
199 *
200 * @return bool Successfulness
201 */
202 public function parse()
203 {
204 if ($this->compressed_size >= $this->min_compressed_size)
205 {
206 // Check ID1, ID2, and CM
207 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
208 {
209 return false;
210 }
211
212 // Get the FLG (FLaGs)
213 $this->flags = ord($this->compressed_data[3]);
214
215 // FLG bits above (1 << 4) are reserved
216 if ($this->flags > 0x1F)
217 {
218 return false;
219 }
220
221 // Advance the pointer after the above
222 $this->position += 4;
223
224 // MTIME
225 $mtime = substr($this->compressed_data, $this->position, 4);
226 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
227 if (current(unpack('S', "\x00\x01")) === 1)
228 {
229 $mtime = strrev($mtime);
230 }
231 $this->MTIME = current(unpack('l', $mtime));
232 $this->position += 4;
233
234 // Get the XFL (eXtra FLags)
235 $this->XFL = ord($this->compressed_data[$this->position++]);
236
237 // Get the OS (Operating System)
238 $this->OS = ord($this->compressed_data[$this->position++]);
239
240 // Parse the FEXTRA
241 if ($this->flags & 4)
242 {
243 // Read subfield IDs
244 $this->SI1 = $this->compressed_data[$this->position++];
245 $this->SI2 = $this->compressed_data[$this->position++];
246
247 // SI2 set to zero is reserved for future use
248 if ($this->SI2 === "\x00")
249 {
250 return false;
251 }
252
253 // Get the length of the extra field
254 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
255 $this->position += 2;
256
257 // Check the length of the string is still valid
258 $this->min_compressed_size += $len + 4;
259 if ($this->compressed_size >= $this->min_compressed_size)
260 {
261 // Set the extra field to the given data
262 $this->extra_field = substr($this->compressed_data, $this->position, $len);
263 $this->position += $len;
264 }
265 else
266 {
267 return false;
268 }
269 }
270
271 // Parse the FNAME
272 if ($this->flags & 8)
273 {
274 // Get the length of the filename
275 $len = strcspn($this->compressed_data, "\x00", $this->position);
276
277 // Check the length of the string is still valid
278 $this->min_compressed_size += $len + 1;
279 if ($this->compressed_size >= $this->min_compressed_size)
280 {
281 // Set the original filename to the given string
282 $this->filename = substr($this->compressed_data, $this->position, $len);
283 $this->position += $len + 1;
284 }
285 else
286 {
287 return false;
288 }
289 }
290
291 // Parse the FCOMMENT
292 if ($this->flags & 16)
293 {
294 // Get the length of the comment
295 $len = strcspn($this->compressed_data, "\x00", $this->position);
296
297 // Check the length of the string is still valid
298 $this->min_compressed_size += $len + 1;
299 if ($this->compressed_size >= $this->min_compressed_size)
300 {
301 // Set the original comment to the given string
302 $this->comment = substr($this->compressed_data, $this->position, $len);
303 $this->position += $len + 1;
304 }
305 else
306 {
307 return false;
308 }
309 }
310
311 // Parse the FHCRC
312 if ($this->flags & 2)
313 {
314 // Check the length of the string is still valid
315 $this->min_compressed_size += $len + 2;
316 if ($this->compressed_size >= $this->min_compressed_size)
317 {
318 // Read the CRC
319 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
320
321 // Check the CRC matches
322 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
323 {
324 $this->position += 2;
325 }
326 else
327 {
328 return false;
329 }
330 }
331 else
332 {
333 return false;
334 }
335 }
336
337 // Decompress the actual data
338 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
339 {
340 return false;
341 }
342 else
343 {
344 $this->position = $this->compressed_size - 8;
345 }
346
347 // Check CRC of data
348 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
349 $this->position += 4;
350 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
351 {
352 return false;
353 }*/
354
355 // Check ISIZE of data
356 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
357 $this->position += 4;
358 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
359 {
360 return false;
361 }
362
363 // Wow, against all odds, we've actually got a valid gzip string
364 return true;
365 }
366 else
367 {
368 return false;
369 }
370 }
371}