]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/class-simplepie.php
Wordpress 2.8.2
[autoinstalls/wordpress.git] / wp-includes / class-simplepie.php
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-2008, Ryan Parman and Geoffrey Sneddon
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.1.3
37  * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
38  * @author Ryan Parman
39  * @author Geoffrey Sneddon
40  * @link http://simplepie.org/ SimplePie
41  * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43  * @todo phpDoc comments
44  */
45
46 /**
47  * SimplePie Name
48  */
49 define('SIMPLEPIE_NAME', 'SimplePie');
50
51 /**
52  * SimplePie Version
53  */
54 define('SIMPLEPIE_VERSION', '1.1.3');
55
56 /**
57  * SimplePie Build
58  */
59 define('SIMPLEPIE_BUILD', 20081219);
60
61 /**
62  * SimplePie Website URL
63  */
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
65
66 /**
67  * SimplePie Useragent
68  * @see SimplePie::set_useragent()
69  */
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
71
72 /**
73  * SimplePie Linkback
74  */
75 define('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  */
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
82
83 /**
84  * Feed Link Element Autodiscovery
85  * @see SimplePie::set_autodiscovery_level()
86  */
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
88
89 /**
90  * Local Feed Extension Autodiscovery
91  * @see SimplePie::set_autodiscovery_level()
92  */
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
94
95 /**
96  * Local Feed Body Autodiscovery
97  * @see SimplePie::set_autodiscovery_level()
98  */
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
100
101 /**
102  * Remote Feed Extension Autodiscovery
103  * @see SimplePie::set_autodiscovery_level()
104  */
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
106
107 /**
108  * Remote Feed Body Autodiscovery
109  * @see SimplePie::set_autodiscovery_level()
110  */
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
112
113 /**
114  * All Feed Autodiscovery
115  * @see SimplePie::set_autodiscovery_level()
116  */
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
118
119 /**
120  * No known feed type
121  */
122 define('SIMPLEPIE_TYPE_NONE', 0);
123
124 /**
125  * RSS 0.90
126  */
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
128
129 /**
130  * RSS 0.91 (Netscape)
131  */
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
133
134 /**
135  * RSS 0.91 (Userland)
136  */
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
138
139 /**
140  * RSS 0.91 (both Netscape and Userland)
141  */
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
143
144 /**
145  * RSS 0.92
146  */
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
148
149 /**
150  * RSS 0.93
151  */
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
153
154 /**
155  * RSS 0.94
156  */
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
158
159 /**
160  * RSS 1.0
161  */
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
163
164 /**
165  * RSS 2.0
166  */
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
168
169 /**
170  * RDF-based RSS
171  */
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
173
174 /**
175  * Non-RDF-based RSS (truly intended as syndication format)
176  */
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
178
179 /**
180  * All RSS
181  */
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
183
184 /**
185  * Atom 0.3
186  */
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
188
189 /**
190  * Atom 1.0
191  */
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
193
194 /**
195  * All Atom
196  */
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
198
199 /**
200  * All feed types
201  */
202 define('SIMPLEPIE_TYPE_ALL', 1023);
203
204 /**
205  * No construct
206  */
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
208
209 /**
210  * Text construct
211  */
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
213
214 /**
215  * HTML construct
216  */
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
218
219 /**
220  * XHTML construct
221  */
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
223
224 /**
225  * base64-encoded construct
226  */
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
228
229 /**
230  * IRI construct
231  */
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
233
234 /**
235  * A construct that might be HTML
236  */
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
238
239 /**
240  * All constructs
241  */
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
243
244 /**
245  * PCRE for HTML attributes
246  */
247 define('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]*');
248
249 /**
250  * PCRE for XML attributes
251  */
252 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
253
254 /**
255  * XML Namespace
256  */
257 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
258
259 /**
260  * Atom 1.0 Namespace
261  */
262 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
263
264 /**
265  * Atom 0.3 Namespace
266  */
267 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
268
269 /**
270  * RDF Namespace
271  */
272 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
273
274 /**
275  * RSS 0.90 Namespace
276  */
277 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
278
279 /**
280  * RSS 1.0 Namespace
281  */
282 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
283
284 /**
285  * RSS 1.0 Content Module Namespace
286  */
287 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
288
289 /**
290  * RSS 2.0 Namespace
291  * (Stupid, I know, but I'm certain it will confuse people less with support.)
292  */
293 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
294
295 /**
296  * DC 1.0 Namespace
297  */
298 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
299
300 /**
301  * DC 1.1 Namespace
302  */
303 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
304
305 /**
306  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
307  */
308 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
309
310 /**
311  * GeoRSS Namespace
312  */
313 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
314
315 /**
316  * Media RSS Namespace
317  */
318 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
319
320 /**
321  * Wrong Media RSS Namespace
322  */
323 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
324
325 /**
326  * iTunes RSS Namespace
327  */
328 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
329
330 /**
331  * XHTML Namespace
332  */
333 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
334
335 /**
336  * IANA Link Relations Registry
337  */
338 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
339
340 /**
341  * Whether we're running on PHP5
342  */
343 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
344
345 /**
346  * No file source
347  */
348 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
349
350 /**
351  * Remote file source
352  */
353 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
354
355 /**
356  * Local file source
357  */
358 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
359
360 /**
361  * fsockopen() file source
362  */
363 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
364
365 /**
366  * cURL file source
367  */
368 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
369
370 /**
371  * file_get_contents() file source
372  */
373 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
374
375 /**
376  * SimplePie
377  *
378  * @package SimplePie
379  * @version "Razzleberry"
380  * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
381  * @author Ryan Parman
382  * @author Geoffrey Sneddon
383  * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
384  */
385 class SimplePie
386 {
387         /**
388          * @var array Raw data
389          * @access private
390          */
391         var $data = array();
392
393         /**
394          * @var mixed Error string
395          * @access private
396          */
397         var $error;
398
399         /**
400          * @var object Instance of SimplePie_Sanitize (or other class)
401          * @see SimplePie::set_sanitize_class()
402          * @access private
403          */
404         var $sanitize;
405
406         /**
407          * @var string SimplePie Useragent
408          * @see SimplePie::set_useragent()
409          * @access private
410          */
411         var $useragent = SIMPLEPIE_USERAGENT;
412
413         /**
414          * @var string Feed URL
415          * @see SimplePie::set_feed_url()
416          * @access private
417          */
418         var $feed_url;
419
420         /**
421          * @var object Instance of SimplePie_File to use as a feed
422          * @see SimplePie::set_file()
423          * @access private
424          */
425         var $file;
426
427         /**
428          * @var string Raw feed data
429          * @see SimplePie::set_raw_data()
430          * @access private
431          */
432         var $raw_data;
433
434         /**
435          * @var int Timeout for fetching remote files
436          * @see SimplePie::set_timeout()
437          * @access private
438          */
439         var $timeout = 10;
440
441         /**
442          * @var bool Forces fsockopen() to be used for remote files instead
443          * of cURL, even if a new enough version is installed
444          * @see SimplePie::force_fsockopen()
445          * @access private
446          */
447         var $force_fsockopen = false;
448
449         /**
450          * @var bool Force the given data/URL to be treated as a feed no matter what
451          * it appears like
452          * @see SimplePie::force_feed()
453          * @access private
454          */
455         var $force_feed = false;
456
457         /**
458          * @var bool Enable/Disable XML dump
459          * @see SimplePie::enable_xml_dump()
460          * @access private
461          */
462         var $xml_dump = false;
463
464         /**
465          * @var bool Enable/Disable Caching
466          * @see SimplePie::enable_cache()
467          * @access private
468          */
469         var $cache = true;
470
471         /**
472          * @var int Cache duration (in seconds)
473          * @see SimplePie::set_cache_duration()
474          * @access private
475          */
476         var $cache_duration = 3600;
477
478         /**
479          * @var int Auto-discovery cache duration (in seconds)
480          * @see SimplePie::set_autodiscovery_cache_duration()
481          * @access private
482          */
483         var $autodiscovery_cache_duration = 604800; // 7 Days.
484
485         /**
486          * @var string Cache location (relative to executing script)
487          * @see SimplePie::set_cache_location()
488          * @access private
489          */
490         var $cache_location = './cache';
491
492         /**
493          * @var string Function that creates the cache filename
494          * @see SimplePie::set_cache_name_function()
495          * @access private
496          */
497         var $cache_name_function = 'md5';
498
499         /**
500          * @var bool Reorder feed by date descending
501          * @see SimplePie::enable_order_by_date()
502          * @access private
503          */
504         var $order_by_date = true;
505
506         /**
507          * @var mixed Force input encoding to be set to the follow value
508          * (false, or anything type-cast to false, disables this feature)
509          * @see SimplePie::set_input_encoding()
510          * @access private
511          */
512         var $input_encoding = false;
513
514         /**
515          * @var int Feed Autodiscovery Level
516          * @see SimplePie::set_autodiscovery_level()
517          * @access private
518          */
519         var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
520
521         /**
522          * @var string Class used for caching feeds
523          * @see SimplePie::set_cache_class()
524          * @access private
525          */
526         var $cache_class = 'SimplePie_Cache';
527
528         /**
529          * @var string Class used for locating feeds
530          * @see SimplePie::set_locator_class()
531          * @access private
532          */
533         var $locator_class = 'SimplePie_Locator';
534
535         /**
536          * @var string Class used for parsing feeds
537          * @see SimplePie::set_parser_class()
538          * @access private
539          */
540         var $parser_class = 'SimplePie_Parser';
541
542         /**
543          * @var string Class used for fetching feeds
544          * @see SimplePie::set_file_class()
545          * @access private
546          */
547         var $file_class = 'SimplePie_File';
548
549         /**
550          * @var string Class used for items
551          * @see SimplePie::set_item_class()
552          * @access private
553          */
554         var $item_class = 'SimplePie_Item';
555
556         /**
557          * @var string Class used for authors
558          * @see SimplePie::set_author_class()
559          * @access private
560          */
561         var $author_class = 'SimplePie_Author';
562
563         /**
564          * @var string Class used for categories
565          * @see SimplePie::set_category_class()
566          * @access private
567          */
568         var $category_class = 'SimplePie_Category';
569
570         /**
571          * @var string Class used for enclosures
572          * @see SimplePie::set_enclosures_class()
573          * @access private
574          */
575         var $enclosure_class = 'SimplePie_Enclosure';
576
577         /**
578          * @var string Class used for Media RSS <media:text> captions
579          * @see SimplePie::set_caption_class()
580          * @access private
581          */
582         var $caption_class = 'SimplePie_Caption';
583
584         /**
585          * @var string Class used for Media RSS <media:copyright>
586          * @see SimplePie::set_copyright_class()
587          * @access private
588          */
589         var $copyright_class = 'SimplePie_Copyright';
590
591         /**
592          * @var string Class used for Media RSS <media:credit>
593          * @see SimplePie::set_credit_class()
594          * @access private
595          */
596         var $credit_class = 'SimplePie_Credit';
597
598         /**
599          * @var string Class used for Media RSS <media:rating>
600          * @see SimplePie::set_rating_class()
601          * @access private
602          */
603         var $rating_class = 'SimplePie_Rating';
604
605         /**
606          * @var string Class used for Media RSS <media:restriction>
607          * @see SimplePie::set_restriction_class()
608          * @access private
609          */
610         var $restriction_class = 'SimplePie_Restriction';
611
612         /**
613          * @var string Class used for content-type sniffing
614          * @see SimplePie::set_content_type_sniffer_class()
615          * @access private
616          */
617         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
618
619         /**
620          * @var string Class used for item sources.
621          * @see SimplePie::set_source_class()
622          * @access private
623          */
624         var $source_class = 'SimplePie_Source';
625
626         /**
627          * @var mixed Set javascript query string parameter (false, or
628          * anything type-cast to false, disables this feature)
629          * @see SimplePie::set_javascript()
630          * @access private
631          */
632         var $javascript = 'js';
633
634         /**
635          * @var int Maximum number of feeds to check with autodiscovery
636          * @see SimplePie::set_max_checked_feeds()
637          * @access private
638          */
639         var $max_checked_feeds = 10;
640
641         /**
642          * @var string Web-accessible path to the handler_favicon.php file.
643          * @see SimplePie::set_favicon_handler()
644          * @access private
645          */
646         var $favicon_handler = '';
647
648         /**
649          * @var string Web-accessible path to the handler_image.php file.
650          * @see SimplePie::set_image_handler()
651          * @access private
652          */
653         var $image_handler = '';
654
655         /**
656          * @var array Stores the URLs when multiple feeds are being initialized.
657          * @see SimplePie::set_feed_url()
658          * @access private
659          */
660         var $multifeed_url = array();
661
662         /**
663          * @var array Stores SimplePie objects when multiple feeds initialized.
664          * @access private
665          */
666         var $multifeed_objects = array();
667
668         /**
669          * @var array Stores the get_object_vars() array for use with multifeeds.
670          * @see SimplePie::set_feed_url()
671          * @access private
672          */
673         var $config_settings = null;
674
675         /**
676          * @var integer Stores the number of items to return per-feed with multifeeds.
677          * @see SimplePie::set_item_limit()
678          * @access private
679          */
680         var $item_limit = 0;
681
682         /**
683          * @var array Stores the default attributes to be stripped by strip_attributes().
684          * @see SimplePie::strip_attributes()
685          * @access private
686          */
687         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
688
689         /**
690          * @var array Stores the default tags to be stripped by strip_htmltags().
691          * @see SimplePie::strip_htmltags()
692          * @access private
693          */
694         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
695
696         /**
697          * The SimplePie class contains feed level data and options
698          *
699          * There are two ways that you can create a new SimplePie object. The first
700          * is by passing a feed URL as a parameter to the SimplePie constructor
701          * (as well as optionally setting the cache location and cache expiry). This
702          * will initialise the whole feed with all of the default settings, and you
703          * can begin accessing methods and properties immediately.
704          *
705          * The second way is to create the SimplePie object with no parameters
706          * at all. This will enable you to set configuration options. After setting
707          * them, you must initialise the feed using $feed->init(). At that point the
708          * object's methods and properties will be available to you. This format is
709          * what is used throughout this documentation.
710          *
711          * @access public
712          * @since 1.0 Preview Release
713          * @param string $feed_url This is the URL you want to parse.
714          * @param string $cache_location This is where you want the cache to be stored.
715          * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
716          */
717         function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
718         {
719                 // Other objects, instances created here so we can set options on them
720                 $this->sanitize =& new SimplePie_Sanitize;
721
722                 // Set options if they're passed to the constructor
723                 if ($cache_location !== null)
724                 {
725                         $this->set_cache_location($cache_location);
726                 }
727
728                 if ($cache_duration !== null)
729                 {
730                         $this->set_cache_duration($cache_duration);
731                 }
732
733                 // Only init the script if we're passed a feed URL
734                 if ($feed_url !== null)
735                 {
736                         $this->set_feed_url($feed_url);
737                         $this->init();
738                 }
739         }
740
741         /**
742          * Used for converting object to a string
743          */
744         function __toString()
745         {
746                 return md5(serialize($this->data));
747         }
748
749         /**
750          * Remove items that link back to this before destroying this object
751          */
752         function __destruct()
753         {
754                 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
755                 {
756                         if (!empty($this->data['items']))
757                         {
758                                 foreach ($this->data['items'] as $item)
759                                 {
760                                         $item->__destruct();
761                                 }
762                                 unset($item, $this->data['items']);
763                         }
764                         if (!empty($this->data['ordered_items']))
765                         {
766                                 foreach ($this->data['ordered_items'] as $item)
767                                 {
768                                         $item->__destruct();
769                                 }
770                                 unset($item, $this->data['ordered_items']);
771                         }
772                 }
773         }
774
775         /**
776          * Force the given data/URL to be treated as a feed no matter what it
777          * appears like
778          *
779          * @access public
780          * @since 1.1
781          * @param bool $enable Force the given data/URL to be treated as a feed
782          */
783         function force_feed($enable = false)
784         {
785                 $this->force_feed = (bool) $enable;
786         }
787
788         /**
789          * This is the URL of the feed you want to parse.
790          *
791          * This allows you to enter the URL of the feed you want to parse, or the
792          * website you want to try to use auto-discovery on. This takes priority
793          * over any set raw data.
794          *
795          * You can set multiple feeds to mash together by passing an array instead
796          * of a string for the $url. Remember that with each additional feed comes
797          * additional processing and resources.
798          *
799          * @access public
800          * @since 1.0 Preview Release
801          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
802          * @see SimplePie::set_raw_data()
803          */
804         function set_feed_url($url)
805         {
806                 if (is_array($url))
807                 {
808                         $this->multifeed_url = array();
809                         foreach ($url as $value)
810                         {
811                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
812                         }
813                 }
814                 else
815                 {
816                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
817                 }
818         }
819
820         /**
821          * Provides an instance of SimplePie_File to use as a feed
822          *
823          * @access public
824          * @param object &$file Instance of SimplePie_File (or subclass)
825          * @return bool True on success, false on failure
826          */
827         function set_file(&$file)
828         {
829                 if (is_a($file, 'SimplePie_File'))
830                 {
831                         $this->feed_url = $file->url;
832                         $this->file =& $file;
833                         return true;
834                 }
835                 return false;
836         }
837
838         /**
839          * Allows you to use a string of RSS/Atom data instead of a remote feed.
840          *
841          * If you have a feed available as a string in PHP, you can tell SimplePie
842          * to parse that data string instead of a remote feed. Any set feed URL
843          * takes precedence.
844          *
845          * @access public
846          * @since 1.0 Beta 3
847          * @param string $data RSS or Atom data as a string.
848          * @see SimplePie::set_feed_url()
849          */
850         function set_raw_data($data)
851         {
852                 $this->raw_data = $data;
853         }
854
855         /**
856          * Allows you to override the default timeout for fetching remote feeds.
857          *
858          * This allows you to change the maximum time the feed's server to respond
859          * and send the feed back.
860          *
861          * @access public
862          * @since 1.0 Beta 3
863          * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
864          */
865         function set_timeout($timeout = 10)
866         {
867                 $this->timeout = (int) $timeout;
868         }
869
870         /**
871          * Forces SimplePie to use fsockopen() instead of the preferred cURL
872          * functions.
873          *
874          * @access public
875          * @since 1.0 Beta 3
876          * @param bool $enable Force fsockopen() to be used
877          */
878         function force_fsockopen($enable = false)
879         {
880                 $this->force_fsockopen = (bool) $enable;
881         }
882
883         /**
884          * Outputs the raw XML content of the feed, after it has gone through
885          * SimplePie's filters.
886          *
887          * Used only for debugging, this function will output the XML content as
888          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
889          * before trying to parse it. Many parts of the feed are re-written in
890          * memory, and in the end, you have a parsable feed. XML dump shows you the
891          * actual XML that SimplePie tries to parse, which may or may not be very
892          * different from the original feed.
893          *
894          * @access public
895          * @since 1.0 Preview Release
896          * @param bool $enable Enable XML dump
897          */
898         function enable_xml_dump($enable = false)
899         {
900                 $this->xml_dump = (bool) $enable;
901         }
902
903         /**
904          * Enables/disables caching in SimplePie.
905          *
906          * This option allows you to disable caching all-together in SimplePie.
907          * However, disabling the cache can lead to longer load times.
908          *
909          * @access public
910          * @since 1.0 Preview Release
911          * @param bool $enable Enable caching
912          */
913         function enable_cache($enable = true)
914         {
915                 $this->cache = (bool) $enable;
916         }
917
918         /**
919          * Set the length of time (in seconds) that the contents of a feed
920          * will be cached.
921          *
922          * @access public
923          * @param int $seconds The feed content cache duration.
924          */
925         function set_cache_duration($seconds = 3600)
926         {
927                 $this->cache_duration = (int) $seconds;
928         }
929
930         /**
931          * Set the length of time (in seconds) that the autodiscovered feed
932          * URL will be cached.
933          *
934          * @access public
935          * @param int $seconds The autodiscovered feed URL cache duration.
936          */
937         function set_autodiscovery_cache_duration($seconds = 604800)
938         {
939                 $this->autodiscovery_cache_duration = (int) $seconds;
940         }
941
942         /**
943          * Set the file system location where the cached files should be stored.
944          *
945          * @access public
946          * @param string $location The file system location.
947          */
948         function set_cache_location($location = './cache')
949         {
950                 $this->cache_location = (string) $location;
951         }
952
953         /**
954          * Determines whether feed items should be sorted into reverse chronological order.
955          *
956          * @access public
957          * @param bool $enable Sort as reverse chronological order.
958          */
959         function enable_order_by_date($enable = true)
960         {
961                 $this->order_by_date = (bool) $enable;
962         }
963
964         /**
965          * Allows you to override the character encoding reported by the feed.
966          *
967          * @access public
968          * @param string $encoding Character encoding.
969          */
970         function set_input_encoding($encoding = false)
971         {
972                 if ($encoding)
973                 {
974                         $this->input_encoding = (string) $encoding;
975                 }
976                 else
977                 {
978                         $this->input_encoding = false;
979                 }
980         }
981
982         /**
983          * Set how much feed autodiscovery to do
984          *
985          * @access public
986          * @see SIMPLEPIE_LOCATOR_NONE
987          * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
988          * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
989          * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
990          * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
991          * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
992          * @see SIMPLEPIE_LOCATOR_ALL
993          * @param int $level Feed Autodiscovery Level (level can be a
994          * combination of the above constants, see bitwise OR operator)
995          */
996         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
997         {
998                 $this->autodiscovery = (int) $level;
999         }
1000
1001         /**
1002          * Allows you to change which class SimplePie uses for caching.
1003          * Useful when you are overloading or extending SimplePie's default classes.
1004          *
1005          * @access public
1006          * @param string $class Name of custom class.
1007          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1008          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1009          */
1010         function set_cache_class($class = 'SimplePie_Cache')
1011         {
1012                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1013                 {
1014                         $this->cache_class = $class;
1015                         return true;
1016                 }
1017                 return false;
1018         }
1019
1020         /**
1021          * Allows you to change which class SimplePie uses for auto-discovery.
1022          * Useful when you are overloading or extending SimplePie's default classes.
1023          *
1024          * @access public
1025          * @param string $class Name of custom class.
1026          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1027          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1028          */
1029         function set_locator_class($class = 'SimplePie_Locator')
1030         {
1031                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1032                 {
1033                         $this->locator_class = $class;
1034                         return true;
1035                 }
1036                 return false;
1037         }
1038
1039         /**
1040          * Allows you to change which class SimplePie uses for XML parsing.
1041          * Useful when you are overloading or extending SimplePie's default classes.
1042          *
1043          * @access public
1044          * @param string $class Name of custom class.
1045          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1046          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1047          */
1048         function set_parser_class($class = 'SimplePie_Parser')
1049         {
1050                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1051                 {
1052                         $this->parser_class = $class;
1053                         return true;
1054                 }
1055                 return false;
1056         }
1057
1058         /**
1059          * Allows you to change which class SimplePie uses for remote file fetching.
1060          * Useful when you are overloading or extending SimplePie's default classes.
1061          *
1062          * @access public
1063          * @param string $class Name of custom class.
1064          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1065          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1066          */
1067         function set_file_class($class = 'SimplePie_File')
1068         {
1069                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1070                 {
1071                         $this->file_class = $class;
1072                         return true;
1073                 }
1074                 return false;
1075         }
1076
1077         /**
1078          * Allows you to change which class SimplePie uses for data sanitization.
1079          * Useful when you are overloading or extending SimplePie's default classes.
1080          *
1081          * @access public
1082          * @param string $class Name of custom class.
1083          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1084          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1085          */
1086         function set_sanitize_class($class = 'SimplePie_Sanitize')
1087         {
1088                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1089                 {
1090                         $this->sanitize =& new $class;
1091                         return true;
1092                 }
1093                 return false;
1094         }
1095
1096         /**
1097          * Allows you to change which class SimplePie uses for handling feed items.
1098          * Useful when you are overloading or extending SimplePie's default classes.
1099          *
1100          * @access public
1101          * @param string $class Name of custom class.
1102          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1103          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1104          */
1105         function set_item_class($class = 'SimplePie_Item')
1106         {
1107                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1108                 {
1109                         $this->item_class = $class;
1110                         return true;
1111                 }
1112                 return false;
1113         }
1114
1115         /**
1116          * Allows you to change which class SimplePie uses for handling author data.
1117          * Useful when you are overloading or extending SimplePie's default classes.
1118          *
1119          * @access public
1120          * @param string $class Name of custom class.
1121          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1122          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1123          */
1124         function set_author_class($class = 'SimplePie_Author')
1125         {
1126                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1127                 {
1128                         $this->author_class = $class;
1129                         return true;
1130                 }
1131                 return false;
1132         }
1133
1134         /**
1135          * Allows you to change which class SimplePie uses for handling category data.
1136          * Useful when you are overloading or extending SimplePie's default classes.
1137          *
1138          * @access public
1139          * @param string $class Name of custom class.
1140          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1141          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1142          */
1143         function set_category_class($class = 'SimplePie_Category')
1144         {
1145                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1146                 {
1147                         $this->category_class = $class;
1148                         return true;
1149                 }
1150                 return false;
1151         }
1152
1153         /**
1154          * Allows you to change which class SimplePie uses for feed enclosures.
1155          * Useful when you are overloading or extending SimplePie's default classes.
1156          *
1157          * @access public
1158          * @param string $class Name of custom class.
1159          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1160          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1161          */
1162         function set_enclosure_class($class = 'SimplePie_Enclosure')
1163         {
1164                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1165                 {
1166                         $this->enclosure_class = $class;
1167                         return true;
1168                 }
1169                 return false;
1170         }
1171
1172         /**
1173          * Allows you to change which class SimplePie uses for <media:text> captions
1174          * Useful when you are overloading or extending SimplePie's default classes.
1175          *
1176          * @access public
1177          * @param string $class Name of custom class.
1178          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1179          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1180          */
1181         function set_caption_class($class = 'SimplePie_Caption')
1182         {
1183                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1184                 {
1185                         $this->caption_class = $class;
1186                         return true;
1187                 }
1188                 return false;
1189         }
1190
1191         /**
1192          * Allows you to change which class SimplePie uses for <media:copyright>
1193          * Useful when you are overloading or extending SimplePie's default classes.
1194          *
1195          * @access public
1196          * @param string $class Name of custom class.
1197          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1198          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1199          */
1200         function set_copyright_class($class = 'SimplePie_Copyright')
1201         {
1202                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1203                 {
1204                         $this->copyright_class = $class;
1205                         return true;
1206                 }
1207                 return false;
1208         }
1209
1210         /**
1211          * Allows you to change which class SimplePie uses for <media:credit>
1212          * Useful when you are overloading or extending SimplePie's default classes.
1213          *
1214          * @access public
1215          * @param string $class Name of custom class.
1216          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1217          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1218          */
1219         function set_credit_class($class = 'SimplePie_Credit')
1220         {
1221                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1222                 {
1223                         $this->credit_class = $class;
1224                         return true;
1225                 }
1226                 return false;
1227         }
1228
1229         /**
1230          * Allows you to change which class SimplePie uses for <media:rating>
1231          * Useful when you are overloading or extending SimplePie's default classes.
1232          *
1233          * @access public
1234          * @param string $class Name of custom class.
1235          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1236          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1237          */
1238         function set_rating_class($class = 'SimplePie_Rating')
1239         {
1240                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1241                 {
1242                         $this->rating_class = $class;
1243                         return true;
1244                 }
1245                 return false;
1246         }
1247
1248         /**
1249          * Allows you to change which class SimplePie uses for <media:restriction>
1250          * Useful when you are overloading or extending SimplePie's default classes.
1251          *
1252          * @access public
1253          * @param string $class Name of custom class.
1254          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1255          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1256          */
1257         function set_restriction_class($class = 'SimplePie_Restriction')
1258         {
1259                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1260                 {
1261                         $this->restriction_class = $class;
1262                         return true;
1263                 }
1264                 return false;
1265         }
1266
1267         /**
1268          * Allows you to change which class SimplePie uses for content-type sniffing.
1269          * Useful when you are overloading or extending SimplePie's default classes.
1270          *
1271          * @access public
1272          * @param string $class Name of custom class.
1273          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1274          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1275          */
1276         function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1277         {
1278                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1279                 {
1280                         $this->content_type_sniffer_class = $class;
1281                         return true;
1282                 }
1283                 return false;
1284         }
1285
1286         /**
1287          * Allows you to change which class SimplePie uses item sources.
1288          * Useful when you are overloading or extending SimplePie's default classes.
1289          *
1290          * @access public
1291          * @param string $class Name of custom class.
1292          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1293          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1294          */
1295         function set_source_class($class = 'SimplePie_Source')
1296         {
1297                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1298                 {
1299                         $this->source_class = $class;
1300                         return true;
1301                 }
1302                 return false;
1303         }
1304
1305         /**
1306          * Allows you to override the default user agent string.
1307          *
1308          * @access public
1309          * @param string $ua New user agent string.
1310          */
1311         function set_useragent($ua = SIMPLEPIE_USERAGENT)
1312         {
1313                 $this->useragent = (string) $ua;
1314         }
1315
1316         /**
1317          * Set callback function to create cache filename with
1318          *
1319          * @access public
1320          * @param mixed $function Callback function
1321          */
1322         function set_cache_name_function($function = 'md5')
1323         {
1324                 if (is_callable($function))
1325                 {
1326                         $this->cache_name_function = $function;
1327                 }
1328         }
1329
1330         /**
1331          * Set javascript query string parameter
1332          *
1333          * @access public
1334          * @param mixed $get Javascript query string parameter
1335          */
1336         function set_javascript($get = 'js')
1337         {
1338                 if ($get)
1339                 {
1340                         $this->javascript = (string) $get;
1341                 }
1342                 else
1343                 {
1344                         $this->javascript = false;
1345                 }
1346         }
1347
1348         /**
1349          * Set options to make SP as fast as possible.  Forgoes a
1350          * substantial amount of data sanitization in favor of speed.
1351          *
1352          * @access public
1353          * @param bool $set Whether to set them or not
1354          */
1355         function set_stupidly_fast($set = false)
1356         {
1357                 if ($set)
1358                 {
1359                         $this->enable_order_by_date(false);
1360                         $this->remove_div(false);
1361                         $this->strip_comments(false);
1362                         $this->strip_htmltags(false);
1363                         $this->strip_attributes(false);
1364                         $this->set_image_handler(false);
1365                 }
1366         }
1367
1368         /**
1369          * Set maximum number of feeds to check with autodiscovery
1370          *
1371          * @access public
1372          * @param int $max Maximum number of feeds to check
1373          */
1374         function set_max_checked_feeds($max = 10)
1375         {
1376                 $this->max_checked_feeds = (int) $max;
1377         }
1378
1379         function remove_div($enable = true)
1380         {
1381                 $this->sanitize->remove_div($enable);
1382         }
1383
1384         function strip_htmltags($tags = '', $encode = null)
1385         {
1386                 if ($tags === '')
1387                 {
1388                         $tags = $this->strip_htmltags;
1389                 }
1390                 $this->sanitize->strip_htmltags($tags);
1391                 if ($encode !== null)
1392                 {
1393                         $this->sanitize->encode_instead_of_strip($tags);
1394                 }
1395         }
1396
1397         function encode_instead_of_strip($enable = true)
1398         {
1399                 $this->sanitize->encode_instead_of_strip($enable);
1400         }
1401
1402         function strip_attributes($attribs = '')
1403         {
1404                 if ($attribs === '')
1405                 {
1406                         $attribs = $this->strip_attributes;
1407                 }
1408                 $this->sanitize->strip_attributes($attribs);
1409         }
1410
1411         function set_output_encoding($encoding = 'UTF-8')
1412         {
1413                 $this->sanitize->set_output_encoding($encoding);
1414         }
1415
1416         function strip_comments($strip = false)
1417         {
1418                 $this->sanitize->strip_comments($strip);
1419         }
1420
1421         /**
1422          * Set element/attribute key/value pairs of HTML attributes
1423          * containing URLs that need to be resolved relative to the feed
1424          *
1425          * @access public
1426          * @since 1.0
1427          * @param array $element_attribute Element/attribute key/value pairs
1428          */
1429         function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1430         {
1431                 $this->sanitize->set_url_replacements($element_attribute);
1432         }
1433
1434         /**
1435          * Set the handler to enable the display of cached favicons.
1436          *
1437          * @access public
1438          * @param str $page Web-accessible path to the handler_favicon.php file.
1439          * @param str $qs The query string that the value should be passed to.
1440          */
1441         function set_favicon_handler($page = false, $qs = 'i')
1442         {
1443                 if ($page != false)
1444                 {
1445                         $this->favicon_handler = $page . '?' . $qs . '=';
1446                 }
1447                 else
1448                 {
1449                         $this->favicon_handler = '';
1450                 }
1451         }
1452
1453         /**
1454          * Set the handler to enable the display of cached images.
1455          *
1456          * @access public
1457          * @param str $page Web-accessible path to the handler_image.php file.
1458          * @param str $qs The query string that the value should be passed to.
1459          */
1460         function set_image_handler($page = false, $qs = 'i')
1461         {
1462                 if ($page != false)
1463                 {
1464                         $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1465                 }
1466                 else
1467                 {
1468                         $this->image_handler = '';
1469                 }
1470         }
1471
1472         /**
1473          * Set the limit for items returned per-feed with multifeeds.
1474          *
1475          * @access public
1476          * @param integer $limit The maximum number of items to return.
1477          */
1478         function set_item_limit($limit = 0)
1479         {
1480                 $this->item_limit = (int) $limit;
1481         }
1482
1483         function init()
1484         {
1485                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1486                 {
1487                         return false;
1488                 }
1489                 if (isset($_GET[$this->javascript]))
1490                 {
1491                         if (function_exists('ob_gzhandler'))
1492                         {
1493                                 ob_start('ob_gzhandler');
1494                         }
1495                         header('Content-type: text/javascript; charset: UTF-8');
1496                         header('Cache-Control: must-revalidate');
1497                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1498                         ?>
1499 function embed_odeo(link) {
1500         document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
1501 }
1502
1503 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1504         if (placeholder != '') {
1505                 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>');
1506         }
1507         else {
1508                 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>');
1509         }
1510 }
1511
1512 function embed_flash(bgcolor, width, height, link, loop, type) {
1513         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>');
1514 }
1515
1516 function embed_flv(width, height, link, placeholder, loop, player) {
1517         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>');
1518 }
1519
1520 function embed_wmedia(width, height, link) {
1521         document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1522 }
1523                         <?php
1524                         exit;
1525                 }
1526
1527                 // Pass whatever was set with config options over to the sanitizer.
1528                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1529                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1530
1531                 if ($this->feed_url !== null || $this->raw_data !== null)
1532                 {
1533                         $this->data = array();
1534                         $this->multifeed_objects = array();
1535                         $cache = false;
1536
1537                         if ($this->feed_url !== null)
1538                         {
1539                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1540                                 // Decide whether to enable caching
1541                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1542                                 {
1543                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1544                                 }
1545                                 // If it's enabled and we don't want an XML dump, use the cache
1546                                 if ($cache && !$this->xml_dump)
1547                                 {
1548                                         // Load the Cache
1549                                         $this->data = $cache->load();
1550                                         if (!empty($this->data))
1551                                         {
1552                                                 // If the cache is for an outdated build of SimplePie
1553                                                 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1554                                                 {
1555                                                         $cache->unlink();
1556                                                         $this->data = array();
1557                                                 }
1558                                                 // If we've hit a collision just rerun it with caching disabled
1559                                                 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1560                                                 {
1561                                                         $cache = false;
1562                                                         $this->data = array();
1563                                                 }
1564                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1565                                                 elseif (isset($this->data['feed_url']))
1566                                                 {
1567                                                         // If the autodiscovery cache is still valid use it.
1568                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1569                                                         {
1570                                                                 // Do not need to do feed autodiscovery yet.
1571                                                                 if ($this->data['feed_url'] == $this->data['url'])
1572                                                                 {
1573                                                                         $cache->unlink();
1574                                                                         $this->data = array();
1575                                                                 }
1576                                                                 else
1577                                                                 {
1578                                                                         $this->set_feed_url($this->data['feed_url']);
1579                                                                         return $this->init();
1580                                                                 }
1581                                                         }
1582                                                 }
1583                                                 // Check if the cache has been updated
1584                                                 elseif ($cache->mtime() + $this->cache_duration < time())
1585                                                 {
1586                                                         // If we have last-modified and/or etag set
1587                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1588                                                         {
1589                                                                 $headers = array();
1590                                                                 if (isset($this->data['headers']['last-modified']))
1591                                                                 {
1592                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1593                                                                 }
1594                                                                 if (isset($this->data['headers']['etag']))
1595                                                                 {
1596                                                                         $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1597                                                                 }
1598                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1599                                                                 if ($file->success)
1600                                                                 {
1601                                                                         if ($file->status_code == 304)
1602                                                                         {
1603                                                                                 $cache->touch();
1604                                                                                 return true;
1605                                                                         }
1606                                                                         else
1607                                                                         {
1608                                                                                 $headers = $file->headers;
1609                                                                         }
1610                                                                 }
1611                                                                 else
1612                                                                 {
1613                                                                         unset($file);
1614                                                                 }
1615                                                         }
1616                                                 }
1617                                                 // If the cache is still valid, just return true
1618                                                 else
1619                                                 {
1620                                                         return true;
1621                                                 }
1622                                         }
1623                                         // If the cache is empty, delete it
1624                                         else
1625                                         {
1626                                                 $cache->unlink();
1627                                                 $this->data = array();
1628                                         }
1629                                 }
1630                                 // 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.
1631                                 if (!isset($file))
1632                                 {
1633                                         if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1634                                         {
1635                                                 $file =& $this->file;
1636                                         }
1637                                         else
1638                                         {
1639                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1640                                         }
1641                                 }
1642                                 // If the file connection has an error, set SimplePie::error to that and quit
1643                                 if (!$file->success)
1644                                 {
1645                                         $this->error = $file->error;
1646                                         if (!empty($this->data))
1647                                         {
1648                                                 return true;
1649                                         }
1650                                         else
1651                                         {
1652                                                 return false;
1653                                         }
1654                                 }
1655
1656                                 if (!$this->force_feed)
1657                                 {
1658                                         // Check if the supplied URL is a feed, if it isn't, look for it.
1659                                         $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1660                                         if (!$locate->is_feed($file))
1661                                         {
1662                                                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1663                                                 unset($file);
1664                                                 if ($file = $locate->find($this->autodiscovery))
1665                                                 {
1666                                                         if ($cache)
1667                                                         {
1668                                                                 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1669                                                                 if (!$cache->save($this))
1670                                                                 {
1671                                                                         trigger_error("$cache->name is not writeable", E_USER_WARNING);
1672                                                                 }
1673                                                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1674                                                         }
1675                                                         $this->feed_url = $file->url;
1676                                                 }
1677                                                 else
1678                                                 {
1679                                                         $this->error = "A feed could not be found at $this->feed_url";
1680                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1681                                                         return false;
1682                                                 }
1683                                         }
1684                                         $locate = null;
1685                                 }
1686
1687                                 $headers = $file->headers;
1688                                 $data = $file->body;
1689                                 $sniffer =& new $this->content_type_sniffer_class($file);
1690                                 $sniffed = $sniffer->get_type();
1691                         }
1692                         else
1693                         {
1694                                 $data = $this->raw_data;
1695                         }
1696
1697                         // Set up array of possible encodings
1698                         $encodings = array();
1699
1700                         // First check to see if input has been overridden.
1701                         if ($this->input_encoding !== false)
1702                         {
1703                                 $encodings[] = $this->input_encoding;
1704                         }
1705
1706                         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1707                         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1708
1709                         // RFC 3023 (only applies to sniffed content)
1710                         if (isset($sniffed))
1711                         {
1712                                 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1713                                 {
1714                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1715                                         {
1716                                                 $encodings[] = strtoupper($charset[1]);
1717                                         }
1718                                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1719                                         $encodings[] = 'UTF-8';
1720                                 }
1721                                 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1722                                 {
1723                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1724                                         {
1725                                                 $encodings[] = $charset[1];
1726                                         }
1727                                         $encodings[] = 'US-ASCII';
1728                                 }
1729                                 // Text MIME-type default
1730                                 elseif (substr($sniffed, 0, 5) === 'text/')
1731                                 {
1732                                         $encodings[] = 'US-ASCII';
1733                                 }
1734                         }
1735
1736                         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1737                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1738                         $encodings[] = 'UTF-8';
1739                         $encodings[] = 'ISO-8859-1';
1740
1741                         // There's no point in trying an encoding twice
1742                         $encodings = array_unique($encodings);
1743
1744                         // If we want the XML, just output that with the most likely encoding and quit
1745                         if ($this->xml_dump)
1746                         {
1747                                 header('Content-type: text/xml; charset=' . $encodings[0]);
1748                                 echo $data;
1749                                 exit;
1750                         }
1751
1752                         // Loop through each possible encoding, till we return something, or run out of possibilities
1753                         foreach ($encodings as $encoding)
1754                         {
1755                                 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1756                                 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1757                                 {
1758                                         // Create new parser
1759                                         $parser =& new $this->parser_class();
1760
1761                                         // If it's parsed fine
1762                                         if ($parser->parse($utf8_data, 'UTF-8'))
1763                                         {
1764                                                 $this->data = $parser->get_data();
1765                                                 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1766                                                 {
1767                                                         if (isset($headers))
1768                                                         {
1769                                                                 $this->data['headers'] = $headers;
1770                                                         }
1771                                                         $this->data['build'] = SIMPLEPIE_BUILD;
1772
1773                                                         // Cache the file if caching is enabled
1774                                                         if ($cache && !$cache->save($this))
1775                                                         {
1776                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1777                                                         }
1778                                                         return true;
1779                                                 }
1780                                                 else
1781                                                 {
1782                                                         $this->error = "A feed could not be found at $this->feed_url";
1783                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1784                                                         return false;
1785                                                 }
1786                                         }
1787                                 }
1788                         }
1789                         // We have an error, just set SimplePie::error to it and quit
1790                         $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1791                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1792                         return false;
1793                 }
1794                 elseif (!empty($this->multifeed_url))
1795                 {
1796                         $i = 0;
1797                         $success = 0;
1798                         $this->multifeed_objects = array();
1799                         foreach ($this->multifeed_url as $url)
1800                         {
1801                                 if (SIMPLEPIE_PHP5)
1802                                 {
1803                                         // This keyword needs to defy coding standards for PHP4 compatibility
1804                                         $this->multifeed_objects[$i] = clone($this);
1805                                 }
1806                                 else
1807                                 {
1808                                         $this->multifeed_objects[$i] = $this;
1809                                 }
1810                                 $this->multifeed_objects[$i]->set_feed_url($url);
1811                                 $success |= $this->multifeed_objects[$i]->init();
1812                                 $i++;
1813                         }
1814                         return (bool) $success;
1815                 }
1816                 else
1817                 {
1818                         return false;
1819                 }
1820         }
1821
1822         /**
1823          * Return the error message for the occured error
1824          *
1825          * @access public
1826          * @return string Error message
1827          */
1828         function error()
1829         {
1830                 return $this->error;
1831         }
1832
1833         function get_encoding()
1834         {
1835                 return $this->sanitize->output_encoding;
1836         }
1837
1838         function handle_content_type($mime = 'text/html')
1839         {
1840                 if (!headers_sent())
1841                 {
1842                         $header = "Content-type: $mime;";
1843                         if ($this->get_encoding())
1844                         {
1845                                 $header .= ' charset=' . $this->get_encoding();
1846                         }
1847                         else
1848                         {
1849                                 $header .= ' charset=UTF-8';
1850                         }
1851                         header($header);
1852                 }
1853         }
1854
1855         function get_type()
1856         {
1857                 if (!isset($this->data['type']))
1858                 {
1859                         $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1860                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1861                         {
1862                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1863                         }
1864                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1865                         {
1866                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1867                         }
1868                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1869                         {
1870                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1871                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1872                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1873                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1874                                 {
1875                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1876                                 }
1877                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1878                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1879                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1880                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1881                                 {
1882                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1883                                 }
1884                         }
1885                         elseif (isset($this->data['child']['']['rss']))
1886                         {
1887                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1888                                 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1889                                 {
1890                                         switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1891                                         {
1892                                                 case '0.91':
1893                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1894                                                         if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1895                                                         {
1896                                                                 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1897                                                                 {
1898                                                                         case '0':
1899                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1900                                                                                 break;
1901
1902                                                                         case '24':
1903                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1904                                                                                 break;
1905                                                                 }
1906                                                         }
1907                                                         break;
1908
1909                                                 case '0.92':
1910                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1911                                                         break;
1912
1913                                                 case '0.93':
1914                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1915                                                         break;
1916
1917                                                 case '0.94':
1918                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1919                                                         break;
1920
1921                                                 case '2.0':
1922                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1923                                                         break;
1924                                         }
1925                                 }
1926                         }
1927                         else
1928                         {
1929                                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1930                         }
1931                 }
1932                 return $this->data['type'];
1933         }
1934
1935         /**
1936          * Returns the URL for the favicon of the feed's website.
1937          *
1938          * @todo Cache atom:icon
1939          * @access public
1940          * @since 1.0
1941          */
1942         function get_favicon()
1943         {
1944                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1945                 {
1946                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1947                 }
1948                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1949                 {
1950                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1951
1952                         if ($this->cache && $this->favicon_handler)
1953                         {
1954                                 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1955                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1956
1957                                 if ($cache->load())
1958                                 {
1959                                         return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1960                                 }
1961                                 else
1962                                 {
1963                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1964
1965                                         if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1966                                         {
1967                                                 $sniffer =& new $this->content_type_sniffer_class($file);
1968                                                 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1969                                                 {
1970                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1971                                                         {
1972                                                                 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1973                                                         }
1974                                                         else
1975                                                         {
1976                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1977                                                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1978                                                         }
1979                                                 }
1980                                         }
1981                                 }
1982                         }
1983                         else
1984                         {
1985                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1986                         }
1987                 }
1988                 return false;
1989         }
1990
1991         /**
1992          * @todo If we have a perm redirect we should return the new URL
1993          * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1994          * @todo Also, |atom:link|@rel=self
1995          */
1996         function subscribe_url()
1997         {
1998                 if ($this->feed_url !== null)
1999                 {
2000                         return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2001                 }
2002                 else
2003                 {
2004                         return null;
2005                 }
2006         }
2007
2008         function subscribe_feed()
2009         {
2010                 if ($this->feed_url !== null)
2011                 {
2012                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2013                 }
2014                 else
2015                 {
2016                         return null;
2017                 }
2018         }
2019
2020         function subscribe_outlook()
2021         {
2022                 if ($this->feed_url !== null)
2023                 {
2024                         return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2025                 }
2026                 else
2027                 {
2028                         return null;
2029                 }
2030         }
2031
2032         function subscribe_podcast()
2033         {
2034                 if ($this->feed_url !== null)
2035                 {
2036                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2037                 }
2038                 else
2039                 {
2040                         return null;
2041                 }
2042         }
2043
2044         function subscribe_itunes()
2045         {
2046                 if ($this->feed_url !== null)
2047                 {
2048                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2049                 }
2050                 else
2051                 {
2052                         return null;
2053                 }
2054         }
2055
2056         /**
2057          * Creates the subscribe_* methods' return data
2058          *
2059          * @access private
2060          * @param string $feed_url String to prefix to the feed URL
2061          * @param string $site_url String to prefix to the site URL (and
2062          * suffix to the feed URL)
2063          * @return mixed URL if feed exists, false otherwise
2064          */
2065         function subscribe_service($feed_url, $site_url = null)
2066         {
2067                 if ($this->subscribe_url())
2068                 {
2069                         $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2070                         if ($site_url !== null && $this->get_link() !== null)
2071                         {
2072                                 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2073                         }
2074                         return $return;
2075                 }
2076                 else
2077                 {
2078                         return null;
2079                 }
2080         }
2081
2082         function subscribe_aol()
2083         {
2084                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2085         }
2086
2087         function subscribe_bloglines()
2088         {
2089                 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2090         }
2091
2092         function subscribe_eskobo()
2093         {
2094                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2095         }
2096
2097         function subscribe_feedfeeds()
2098         {
2099                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2100         }
2101
2102         function subscribe_feedster()
2103         {
2104                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2105         }
2106
2107         function subscribe_google()
2108         {
2109                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2110         }
2111
2112         function subscribe_gritwire()
2113         {
2114                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2115         }
2116
2117         function subscribe_msn()
2118         {
2119                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2120         }
2121
2122         function subscribe_netvibes()
2123         {
2124                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2125         }
2126
2127         function subscribe_newsburst()
2128         {
2129                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2130         }
2131
2132         function subscribe_newsgator()
2133         {
2134                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2135         }
2136
2137         function subscribe_odeo()
2138         {
2139                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2140         }
2141
2142         function subscribe_podnova()
2143         {
2144                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2145         }
2146
2147         function subscribe_rojo()
2148         {
2149                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2150         }
2151
2152         function subscribe_yahoo()
2153         {
2154                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2155         }
2156
2157         function get_feed_tags($namespace, $tag)
2158         {
2159                 $type = $this->get_type();
2160                 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2161                 {
2162                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2163                         {
2164                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2165                         }
2166                 }
2167                 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2168                 {
2169                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2170                         {
2171                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2172                         }
2173                 }
2174                 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2175                 {
2176                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2177                         {
2178                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2179                         }
2180                 }
2181                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2182                 {
2183                         if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2184                         {
2185                                 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2186                         }
2187                 }
2188                 return null;
2189         }
2190
2191         function get_channel_tags($namespace, $tag)
2192         {
2193                 $type = $this->get_type();
2194                 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2195                 {
2196                         if ($return = $this->get_feed_tags($namespace, $tag))
2197                         {
2198                                 return $return;
2199                         }
2200                 }
2201                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2202                 {
2203                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2204                         {
2205                                 if (isset($channel[0]['child'][$namespace][$tag]))
2206                                 {
2207                                         return $channel[0]['child'][$namespace][$tag];
2208                                 }
2209                         }
2210                 }
2211                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2212                 {
2213                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2214                         {
2215                                 if (isset($channel[0]['child'][$namespace][$tag]))
2216                                 {
2217                                         return $channel[0]['child'][$namespace][$tag];
2218                                 }
2219                         }
2220                 }
2221                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2222                 {
2223                         if ($channel = $this->get_feed_tags('', 'channel'))
2224                         {
2225                                 if (isset($channel[0]['child'][$namespace][$tag]))
2226                                 {
2227                                         return $channel[0]['child'][$namespace][$tag];
2228                                 }
2229                         }
2230                 }
2231                 return null;
2232         }
2233
2234         function get_image_tags($namespace, $tag)
2235         {
2236                 $type = $this->get_type();
2237                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2238                 {
2239                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2240                         {
2241                                 if (isset($image[0]['child'][$namespace][$tag]))
2242                                 {
2243                                         return $image[0]['child'][$namespace][$tag];
2244                                 }
2245                         }
2246                 }
2247                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2248                 {
2249                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2250                         {
2251                                 if (isset($image[0]['child'][$namespace][$tag]))
2252                                 {
2253                                         return $image[0]['child'][$namespace][$tag];
2254                                 }
2255                         }
2256                 }
2257                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2258                 {
2259                         if ($image = $this->get_channel_tags('', 'image'))
2260                         {
2261                                 if (isset($image[0]['child'][$namespace][$tag]))
2262                                 {
2263                                         return $image[0]['child'][$namespace][$tag];
2264                                 }
2265                         }
2266                 }
2267                 return null;
2268         }
2269
2270         function get_base($element = array())
2271         {
2272                 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2273                 {
2274                         return $element['xml_base'];
2275                 }
2276                 elseif ($this->get_link() !== null)
2277                 {
2278                         return $this->get_link();
2279                 }
2280                 else
2281                 {
2282                         return $this->subscribe_url();
2283                 }
2284         }
2285
2286         function sanitize($data, $type, $base = '')
2287         {
2288                 return $this->sanitize->sanitize($data, $type, $base);
2289         }
2290
2291         function get_title()
2292         {
2293                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2294                 {
2295                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2296                 }
2297                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2298                 {
2299                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2300                 }
2301                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2302                 {
2303                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2304                 }
2305                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2306                 {
2307                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2308                 }
2309                 elseif ($return = $this->get_channel_tags('', 'title'))
2310                 {
2311                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2312                 }
2313                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2314                 {
2315                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2316                 }
2317                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2318                 {
2319                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2320                 }
2321                 else
2322                 {
2323                         return null;
2324                 }
2325         }
2326
2327         function get_category($key = 0)
2328         {
2329                 $categories = $this->get_categories();
2330                 if (isset($categories[$key]))
2331                 {
2332                         return $categories[$key];
2333                 }
2334                 else
2335                 {
2336                         return null;
2337                 }
2338         }
2339
2340         function get_categories()
2341         {
2342                 $categories = array();
2343
2344                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2345                 {
2346                         $term = null;
2347                         $scheme = null;
2348                         $label = null;
2349                         if (isset($category['attribs']['']['term']))
2350                         {
2351                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2352                         }
2353                         if (isset($category['attribs']['']['scheme']))
2354                         {
2355                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2356                         }
2357                         if (isset($category['attribs']['']['label']))
2358                         {
2359                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2360                         }
2361                         $categories[] =& new $this->category_class($term, $scheme, $label);
2362                 }
2363                 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2364                 {
2365                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2366                 }
2367                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2368                 {
2369                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2370                 }
2371                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2372                 {
2373                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2374                 }
2375
2376                 if (!empty($categories))
2377                 {
2378                         return SimplePie_Misc::array_unique($categories);
2379                 }
2380                 else
2381                 {
2382                         return null;
2383                 }
2384         }
2385
2386         function get_author($key = 0)
2387         {
2388                 $authors = $this->get_authors();
2389                 if (isset($authors[$key]))
2390                 {
2391                         return $authors[$key];
2392                 }
2393                 else
2394                 {
2395                         return null;
2396                 }
2397         }
2398
2399         function get_authors()
2400         {
2401                 $authors = array();
2402                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2403                 {
2404                         $name = null;
2405                         $uri = null;
2406                         $email = null;
2407                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2408                         {
2409                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2410                         }
2411                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2412                         {
2413                                 $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]));
2414                         }
2415                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2416                         {
2417                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2418                         }
2419                         if ($name !== null || $email !== null || $uri !== null)
2420                         {
2421                                 $authors[] =& new $this->author_class($name, $uri, $email);
2422                         }
2423                 }
2424                 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2425                 {
2426                         $name = null;
2427                         $url = null;
2428                         $email = null;
2429                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2430                         {
2431                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2432                         }
2433                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2434                         {
2435                                 $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]));
2436                         }
2437                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2438                         {
2439                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2440                         }
2441                         if ($name !== null || $email !== null || $url !== null)
2442                         {
2443                                 $authors[] =& new $this->author_class($name, $url, $email);
2444                         }
2445                 }
2446                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2447                 {
2448                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2449                 }
2450                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2451                 {
2452                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2453                 }
2454                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2455                 {
2456                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2457                 }
2458
2459                 if (!empty($authors))
2460                 {
2461                         return SimplePie_Misc::array_unique($authors);
2462                 }
2463                 else
2464                 {
2465                         return null;
2466                 }
2467         }
2468
2469         function get_contributor($key = 0)
2470         {
2471                 $contributors = $this->get_contributors();
2472                 if (isset($contributors[$key]))
2473                 {
2474                         return $contributors[$key];
2475                 }
2476                 else
2477                 {
2478                         return null;
2479                 }
2480         }
2481
2482         function get_contributors()
2483         {
2484                 $contributors = array();
2485                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2486                 {
2487                         $name = null;
2488                         $uri = null;
2489                         $email = null;
2490                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2491                         {
2492                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2493                         }
2494                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2495                         {
2496                                 $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]));
2497                         }
2498                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2499                         {
2500                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2501                         }
2502                         if ($name !== null || $email !== null || $uri !== null)
2503                         {
2504                                 $contributors[] =& new $this->author_class($name, $uri, $email);
2505                         }
2506                 }
2507                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2508                 {
2509                         $name = null;
2510                         $url = null;
2511                         $email = null;
2512                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2513                         {
2514                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2515                         }
2516                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2517                         {
2518                                 $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]));
2519                         }
2520                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2521                         {
2522                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2523                         }
2524                         if ($name !== null || $email !== null || $url !== null)
2525                         {
2526                                 $contributors[] =& new $this->author_class($name, $url, $email);
2527                         }
2528                 }
2529
2530                 if (!empty($contributors))
2531                 {
2532                         return SimplePie_Misc::array_unique($contributors);
2533                 }
2534                 else
2535                 {
2536                         return null;
2537                 }
2538         }
2539
2540         function get_link($key = 0, $rel = 'alternate')
2541         {
2542                 $links = $this->get_links($rel);
2543                 if (isset($links[$key]))
2544                 {
2545                         return $links[$key];
2546                 }
2547                 else
2548                 {
2549                         return null;
2550                 }
2551         }
2552
2553         /**
2554          * Added for parity between the parent-level and the item/entry-level.
2555          */
2556         function get_permalink()
2557         {
2558                 return $this->get_link(0);
2559         }
2560
2561         function get_links($rel = 'alternate')
2562         {
2563                 if (!isset($this->data['links']))
2564                 {
2565                         $this->data['links'] = array();
2566                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2567                         {
2568                                 foreach ($links as $link)
2569                                 {
2570                                         if (isset($link['attribs']['']['href']))
2571                                         {
2572                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2573                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2574                                         }
2575                                 }
2576                         }
2577                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2578                         {
2579                                 foreach ($links as $link)
2580                                 {
2581                                         if (isset($link['attribs']['']['href']))
2582                                         {
2583                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2584                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2585
2586                                         }
2587                                 }
2588                         }
2589                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2590                         {
2591                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2592                         }
2593                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2594                         {
2595                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2596                         }
2597                         if ($links = $this->get_channel_tags('', 'link'))
2598                         {
2599                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2600                         }
2601
2602                         $keys = array_keys($this->data['links']);
2603                         foreach ($keys as $key)
2604                         {
2605                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
2606                                 {
2607                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2608                                         {
2609                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2610                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2611                                         }
2612                                         else
2613                                         {
2614                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2615                                         }
2616                                 }
2617                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2618                                 {
2619                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2620                                 }
2621                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2622                         }
2623                 }
2624
2625                 if (isset($this->data['links'][$rel]))
2626                 {
2627                         return $this->data['links'][$rel];
2628                 }
2629                 else
2630                 {
2631                         return null;
2632                 }
2633         }
2634
2635         function get_description()
2636         {
2637                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2638                 {
2639                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2640                 }
2641                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2642                 {
2643                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2644                 }
2645                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2646                 {
2647                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2648                 }
2649                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2650                 {
2651                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2652                 }
2653                 elseif ($return = $this->get_channel_tags('', 'description'))
2654                 {
2655                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2656                 }
2657                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2658                 {
2659                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2660                 }
2661                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2662                 {
2663                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2664                 }
2665                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2666                 {
2667                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2668                 }
2669                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2670                 {
2671                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2672                 }
2673                 else
2674                 {
2675                         return null;
2676                 }
2677         }
2678
2679         function get_copyright()
2680         {
2681                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2682                 {
2683                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2684                 }
2685                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2686                 {
2687                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2688                 }
2689                 elseif ($return = $this->get_channel_tags('', 'copyright'))
2690                 {
2691                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2692                 }
2693                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2694                 {
2695                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2696                 }
2697                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2698                 {
2699                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2700                 }
2701                 else
2702                 {
2703                         return null;
2704                 }
2705         }
2706
2707         function get_language()
2708         {
2709                 if ($return = $this->get_channel_tags('', 'language'))
2710                 {
2711                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2712                 }
2713                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2714                 {
2715                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2716                 }
2717                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2718                 {
2719                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2720                 }
2721                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2722                 {
2723                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2724                 }
2725                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2726                 {
2727                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2728                 }
2729                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2730                 {
2731                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2732                 }
2733                 elseif (isset($this->data['headers']['content-language']))
2734                 {
2735                         return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2736                 }
2737                 else
2738                 {
2739                         return null;
2740                 }
2741         }
2742
2743         function get_latitude()
2744         {
2745                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2746                 {
2747                         return (float) $return[0]['data'];
2748                 }
2749                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2750                 {
2751                         return (float) $match[1];
2752                 }
2753                 else
2754                 {
2755                         return null;
2756                 }
2757         }
2758
2759         function get_longitude()
2760         {
2761                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2762                 {
2763                         return (float) $return[0]['data'];
2764                 }
2765                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2766                 {
2767                         return (float) $return[0]['data'];
2768                 }
2769                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2770                 {
2771                         return (float) $match[2];
2772                 }
2773                 else
2774                 {
2775                         return null;
2776                 }
2777         }
2778
2779         function get_image_title()
2780         {
2781                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2782                 {
2783                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2784                 }
2785                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2786                 {
2787                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2788                 }
2789                 elseif ($return = $this->get_image_tags('', 'title'))
2790                 {
2791                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2792                 }
2793                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2794                 {
2795                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2796                 }
2797                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2798                 {
2799                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2800                 }
2801                 else
2802                 {
2803                         return null;
2804                 }
2805         }
2806
2807         function get_image_url()
2808         {
2809                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2810                 {
2811                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2812                 }
2813                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2814                 {
2815                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2816                 }
2817                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2818                 {
2819                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2820                 }
2821                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2822                 {
2823                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2824                 }
2825                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2826                 {
2827                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2828                 }
2829                 elseif ($return = $this->get_image_tags('', 'url'))
2830                 {
2831                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2832                 }
2833                 else
2834                 {
2835                         return null;
2836                 }
2837         }
2838
2839         function get_image_link()
2840         {
2841                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2842                 {
2843                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2844                 }
2845                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2846                 {
2847                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2848                 }
2849                 elseif ($return = $this->get_image_tags('', 'link'))
2850                 {
2851                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2852                 }
2853                 else
2854                 {
2855                         return null;
2856                 }
2857         }
2858
2859         function get_image_width()
2860         {
2861                 if ($return = $this->get_image_tags('', 'width'))
2862                 {
2863                         return round($return[0]['data']);
2864                 }
2865                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2866                 {
2867                         return 88.0;
2868                 }
2869                 else
2870                 {
2871                         return null;
2872                 }
2873         }
2874
2875         function get_image_height()
2876         {
2877                 if ($return = $this->get_image_tags('', 'height'))
2878                 {
2879                         return round($return[0]['data']);
2880                 }
2881                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2882                 {
2883                         return 31.0;
2884                 }
2885                 else
2886                 {
2887                         return null;
2888                 }
2889         }
2890
2891         function get_item_quantity($max = 0)
2892         {
2893                 $qty = count($this->get_items());
2894                 if ($max == 0)
2895                 {
2896                         return $qty;
2897                 }
2898                 else
2899                 {
2900                         return ($qty > $max) ? $max : $qty;
2901                 }
2902         }
2903
2904         function get_item($key = 0)
2905         {
2906                 $items = $this->get_items();
2907                 if (isset($items[$key]))
2908                 {
2909                         return $items[$key];
2910                 }
2911                 else
2912                 {
2913                         return null;
2914                 }
2915         }
2916
2917         function get_items($start = 0, $end = 0)
2918         {
2919                 if (!empty($this->multifeed_objects))
2920                 {
2921                         return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2922                 }
2923                 elseif (!isset($this->data['items']))
2924                 {
2925                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2926                         {
2927                                 $keys = array_keys($items);
2928                                 foreach ($keys as $key)
2929                                 {
2930                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2931                                 }
2932                         }
2933                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2934                         {
2935                                 $keys = array_keys($items);
2936                                 foreach ($keys as $key)
2937                                 {
2938                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2939                                 }
2940                         }
2941                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2942                         {
2943                                 $keys = array_keys($items);
2944                                 foreach ($keys as $key)
2945                                 {
2946                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2947                                 }
2948                         }
2949                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2950                         {
2951                                 $keys = array_keys($items);
2952                                 foreach ($keys as $key)
2953                                 {
2954                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2955                                 }
2956                         }
2957                         if ($items = $this->get_channel_tags('', 'item'))
2958                         {
2959                                 $keys = array_keys($items);
2960                                 foreach ($keys as $key)
2961                                 {
2962                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2963                                 }
2964                         }
2965                 }
2966
2967                 if (!empty($this->data['items']))
2968                 {
2969                         // If we want to order it by date, check if all items have a date, and then sort it
2970                         if ($this->order_by_date)
2971                         {
2972                                 if (!isset($this->data['ordered_items']))
2973                                 {
2974                                         $do_sort = true;
2975                                         foreach ($this->data['items'] as $item)
2976                                         {
2977                                                 if (!$item->get_date('U'))
2978                                                 {
2979                                                         $do_sort = false;
2980                                                         break;
2981                                                 }
2982                                         }
2983                                         $item = null;
2984                                         $this->data['ordered_items'] = $this->data['items'];
2985                                         if ($do_sort)
2986                                         {
2987                                                 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2988                                         }
2989                                 }
2990                                 $items = $this->data['ordered_items'];
2991                         }
2992                         else
2993                         {
2994                                 $items = $this->data['items'];
2995                         }
2996
2997                         // Slice the data as desired
2998                         if ($end == 0)
2999                         {
3000                                 return array_slice($items, $start);
3001                         }
3002                         else
3003                         {
3004                                 return array_slice($items, $start, $end);
3005                         }
3006                 }
3007                 else
3008                 {
3009                         return array();
3010                 }
3011         }
3012
3013         function sort_items($a, $b)
3014         {
3015                 return $a->get_date('U') <= $b->get_date('U');
3016         }
3017
3018         function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3019         {
3020                 if (is_array($urls) && sizeof($urls) > 0)
3021                 {
3022                         $items = array();
3023                         foreach ($urls as $arg)
3024                         {
3025                                 if (is_a($arg, 'SimplePie'))
3026                                 {
3027                                         $items = array_merge($items, $arg->get_items(0, $limit));
3028                                 }
3029                                 else
3030                                 {
3031                                         trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3032                                 }
3033                         }
3034
3035                         $do_sort = true;
3036                         foreach ($items as $item)
3037                         {
3038                                 if (!$item->get_date('U'))
3039                                 {
3040                                         $do_sort = false;
3041                                         break;
3042                                 }
3043                         }
3044                         $item = null;
3045                         if ($do_sort)
3046                         {
3047                                 usort($items, array('SimplePie', 'sort_items'));
3048                         }
3049
3050                         if ($end == 0)
3051                         {
3052                                 return array_slice($items, $start);
3053                         }
3054                         else
3055                         {
3056                                 return array_slice($items, $start, $end);
3057                         }
3058                 }
3059                 else
3060                 {
3061                         trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3062                         return array();
3063                 }
3064         }
3065 }
3066
3067 class SimplePie_Item
3068 {
3069         var $feed;
3070         var $data = array();
3071
3072         function SimplePie_Item($feed, $data)
3073         {
3074                 $this->feed = $feed;
3075                 $this->data = $data;
3076         }
3077
3078         function __toString()
3079         {
3080                 return md5(serialize($this->data));
3081         }
3082
3083         /**
3084          * Remove items that link back to this before destroying this object
3085          */
3086         function __destruct()
3087         {
3088                 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3089                 {
3090                         unset($this->feed);
3091                 }
3092         }
3093
3094         function get_item_tags($namespace, $tag)
3095         {
3096                 if (isset($this->data['child'][$namespace][$tag]))
3097                 {
3098                         return $this->data['child'][$namespace][$tag];
3099                 }
3100                 else
3101                 {
3102                         return null;
3103                 }
3104         }
3105
3106         function get_base($element = array())
3107         {
3108                 return $this->feed->get_base($element);
3109         }
3110
3111         function sanitize($data, $type, $base = '')
3112         {
3113                 return $this->feed->sanitize($data, $type, $base);
3114         }
3115
3116         function get_feed()
3117         {
3118                 return $this->feed;
3119         }
3120
3121         function get_id($hash = false)
3122         {
3123                 if (!$hash)
3124                 {
3125                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3126                         {
3127                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3128                         }
3129                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3130                         {
3131                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3132                         }
3133                         elseif ($return = $this->get_item_tags('', 'guid'))
3134                         {
3135                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3136                         }
3137                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3138                         {
3139                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3140                         }
3141                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3142                         {
3143                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3144                         }
3145                         elseif (($return = $this->get_permalink()) !== null)
3146                         {
3147                                 return $return;
3148                         }
3149                         elseif (($return = $this->get_title()) !== null)
3150                         {
3151                                 return $return;
3152                         }
3153                 }
3154                 if ($this->get_permalink() !== null || $this->get_title() !== null)
3155                 {
3156                         return md5($this->get_permalink() . $this->get_title());
3157                 }
3158                 else
3159                 {
3160                         return md5(serialize($this->data));
3161                 }
3162         }
3163
3164         function get_title()
3165         {
3166                 if (!isset($this->data['title']))
3167                 {
3168                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3169                         {
3170                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3171                         }
3172                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3173                         {
3174                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3175                         }
3176                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3177                         {
3178                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3179                         }
3180                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3181                         {
3182                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3183                         }
3184                         elseif ($return = $this->get_item_tags('', 'title'))
3185                         {
3186                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3187                         }
3188                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3189                         {
3190                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3191                         }
3192                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3193                         {
3194                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3195                         }
3196                         else
3197                         {
3198                                 $this->data['title'] = null;
3199                         }
3200                 }
3201                 return $this->data['title'];
3202         }
3203
3204         function get_description($description_only = false)
3205         {
3206                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3207                 {
3208                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3209                 }
3210                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3211                 {
3212                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3213                 }
3214                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3215                 {
3216                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3217                 }
3218                 elseif ($return = $this->get_item_tags('', 'description'))
3219                 {
3220                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3221                 }
3222                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3223                 {
3224                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3225                 }
3226                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3227                 {
3228                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3229                 }
3230                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3231                 {
3232                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3233                 }
3234                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3235                 {
3236                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3237                 }
3238                 elseif (!$description_only)
3239                 {
3240                         return $this->get_content(true);
3241                 }
3242                 else
3243                 {
3244                         return null;
3245                 }
3246         }
3247
3248         function get_content($content_only = false)
3249         {
3250                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3251                 {
3252                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3253                 }
3254                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3255                 {
3256                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3257                 }
3258                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3259                 {
3260                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3261                 }
3262                 elseif (!$content_only)
3263                 {
3264                         return $this->get_description(true);
3265                 }
3266                 else
3267                 {
3268                         return null;
3269                 }
3270         }
3271
3272         function get_category($key = 0)
3273         {
3274                 $categories = $this->get_categories();
3275                 if (isset($categories[$key]))
3276                 {
3277                         return $categories[$key];
3278                 }
3279                 else
3280                 {
3281                         return null;
3282                 }
3283         }
3284
3285         function get_categories()
3286         {
3287                 $categories = array();
3288
3289                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3290                 {
3291                         $term = null;
3292                         $scheme = null;
3293                         $label = null;
3294                         if (isset($category['attribs']['']['term']))
3295                         {
3296                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3297                         }
3298                         if (isset($category['attribs']['']['scheme']))
3299                         {
3300                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3301                         }
3302                         if (isset($category['attribs']['']['label']))
3303                         {
3304                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3305                         }
3306                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3307                 }
3308                 foreach ((array) $this->get_item_tags('', 'category') as $category)
3309                 {
3310                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3311                 }
3312                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3313                 {
3314                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3315                 }
3316                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3317                 {
3318                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3319                 }
3320
3321                 if (!empty($categories))
3322                 {
3323                         return SimplePie_Misc::array_unique($categories);
3324                 }
3325                 else
3326                 {
3327                         return null;
3328                 }
3329         }
3330
3331         function get_author($key = 0)
3332         {
3333                 $authors = $this->get_authors();
3334                 if (isset($authors[$key]))
3335                 {
3336                         return $authors[$key];
3337                 }
3338                 else
3339                 {
3340                         return null;
3341                 }
3342         }
3343
3344         function get_contributor($key = 0)
3345         {
3346                 $contributors = $this->get_contributors();
3347                 if (isset($contributors[$key]))
3348                 {
3349                         return $contributors[$key];
3350                 }
3351                 else
3352                 {
3353                         return null;
3354                 }
3355         }
3356
3357         function get_contributors()
3358         {
3359                 $contributors = array();
3360                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3361                 {
3362                         $name = null;
3363                         $uri = null;
3364                         $email = null;
3365                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3366                         {
3367                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3368                         }
3369                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3370                         {
3371                                 $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]));
3372                         }
3373                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3374                         {
3375                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3376                         }
3377                         if ($name !== null || $email !== null || $uri !== null)
3378                         {
3379                                 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3380                         }
3381                 }
3382                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3383                 {
3384                         $name = null;
3385                         $url = null;
3386                         $email = null;
3387                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3388                         {
3389                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3390                         }
3391                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3392                         {
3393                                 $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]));
3394                         }
3395                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3396                         {
3397                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3398                         }
3399                         if ($name !== null || $email !== null || $url !== null)
3400                         {
3401                                 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3402                         }
3403                 }
3404
3405                 if (!empty($contributors))
3406                 {
3407                         return SimplePie_Misc::array_unique($contributors);
3408                 }
3409                 else
3410                 {
3411                         return null;
3412                 }
3413         }
3414
3415         /**
3416          * @todo Atom inheritance (item author, source author, feed author)
3417          */
3418         function get_authors()
3419         {
3420                 $authors = array();
3421                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3422                 {
3423                         $name = null;
3424                         $uri = null;
3425                         $email = null;
3426                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3427                         {
3428                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3429                         }
3430                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3431                         {
3432                                 $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]));
3433                         }
3434                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3435                         {
3436                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3437                         }
3438                         if ($name !== null || $email !== null || $uri !== null)
3439                         {
3440                                 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3441                         }
3442                 }
3443                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3444                 {
3445                         $name = null;
3446                         $url = null;
3447                         $email = null;
3448                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3449                         {
3450                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3451                         }
3452                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3453                         {
3454                                 $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]));
3455                         }
3456                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3457                         {
3458                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3459                         }
3460                         if ($name !== null || $email !== null || $url !== null)
3461                         {
3462                                 $authors[] =& new $this->feed->author_class($name, $url, $email);
3463                         }
3464                 }
3465                 if ($author = $this->get_item_tags('', 'author'))
3466                 {
3467                         $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3468                 }
3469                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3470                 {
3471                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3472                 }
3473                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3474                 {
3475                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3476                 }
3477                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3478                 {
3479                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3480                 }
3481
3482                 if (!empty($authors))
3483                 {
3484                         return SimplePie_Misc::array_unique($authors);
3485                 }
3486                 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3487                 {
3488                         return $authors;
3489                 }
3490                 elseif ($authors = $this->feed->get_authors())
3491                 {
3492                         return $authors;
3493                 }
3494                 else
3495                 {
3496                         return null;
3497                 }
3498         }
3499
3500         function get_copyright()
3501         {
3502                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3503                 {
3504                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3505                 }
3506                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3507                 {
3508                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3509                 }
3510                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3511                 {
3512                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3513                 }
3514                 else
3515                 {
3516                         return null;
3517                 }
3518         }
3519
3520         function get_date($date_format = 'j F Y, g:i a')
3521         {
3522                 if (!isset($this->data['date']))
3523                 {
3524                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3525                         {
3526                                 $this->data['date']['raw'] = $return[0]['data'];
3527                         }
3528                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3529                         {
3530                                 $this->data['date']['raw'] = $return[0]['data'];
3531                         }
3532                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3533                         {
3534                                 $this->data['date']['raw'] = $return[0]['data'];
3535                         }
3536                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3537                         {
3538                                 $this->data['date']['raw'] = $return[0]['data'];
3539                         }
3540                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3541                         {
3542                                 $this->data['date']['raw'] = $return[0]['data'];
3543                         }
3544                         elseif ($return = $this->get_item_tags('', 'pubDate'))
3545                         {
3546                                 $this->data['date']['raw'] = $return[0]['data'];
3547                         }
3548                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3549                         {
3550                                 $this->data['date']['raw'] = $return[0]['data'];
3551                         }
3552                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3553                         {
3554                                 $this->data['date']['raw'] = $return[0]['data'];
3555                         }
3556
3557                         if (!empty($this->data['date']['raw']))
3558                         {
3559                                 $parser = SimplePie_Parse_Date::get();
3560                                 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3561                         }
3562                         else
3563                         {
3564                                 $this->data['date'] = null;
3565                         }
3566                 }
3567                 if ($this->data['date'])
3568                 {
3569                         $date_format = (string) $date_format;
3570                         switch ($date_format)
3571                         {
3572                                 case '':
3573                                         return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3574
3575                                 case 'U':
3576                                         return $this->data['date']['parsed'];
3577
3578                                 default:
3579                                         return date($date_format, $this->data['date']['parsed']);
3580                         }
3581                 }
3582                 else
3583                 {
3584                         return null;
3585                 }
3586         }
3587
3588         function get_local_date($date_format = '%c')
3589         {
3590                 if (!$date_format)
3591                 {
3592                         return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3593                 }
3594                 elseif (($date = $this->get_date('U')) !== null)
3595                 {
3596                         return strftime($date_format, $date);
3597                 }
3598                 else
3599                 {
3600                         return null;
3601                 }
3602         }
3603
3604         function get_permalink()
3605         {
3606                 $link = $this->get_link();
3607                 $enclosure = $this->get_enclosure(0);
3608                 if ($link !== null)
3609                 {
3610                         return $link;
3611                 }
3612                 elseif ($enclosure !== null)
3613                 {
3614                         return $enclosure->get_link();
3615                 }
3616                 else
3617                 {
3618                         return null;
3619                 }
3620         }
3621
3622         function get_link($key = 0, $rel = 'alternate')
3623         {
3624                 $links = $this->get_links($rel);
3625                 if ($links[$key] !== null)
3626                 {
3627                         return $links[$key];
3628                 }
3629                 else
3630                 {
3631                         return null;
3632                 }
3633         }
3634
3635         function get_links($rel = 'alternate')
3636         {
3637                 if (!isset($this->data['links']))
3638                 {
3639                         $this->data['links'] = array();
3640                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3641                         {
3642                                 if (isset($link['attribs']['']['href']))
3643                                 {
3644                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3645                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3646
3647                                 }
3648                         }
3649                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3650                         {
3651                                 if (isset($link['attribs']['']['href']))
3652                                 {
3653                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3654                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3655                                 }
3656                         }
3657                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3658                         {
3659                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3660                         }
3661                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3662                         {
3663                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3664                         }
3665                         if ($links = $this->get_item_tags('', 'link'))
3666                         {
3667                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3668                         }
3669                         if ($links = $this->get_item_tags('', 'guid'))
3670                         {
3671                                 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3672                                 {
3673                                         $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3674                                 }
3675                         }
3676
3677                         $keys = array_keys($this->data['links']);
3678                         foreach ($keys as $key)
3679                         {
3680                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
3681                                 {
3682                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3683                                         {
3684                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3685                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3686                                         }
3687                                         else
3688                                         {
3689                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3690                                         }
3691                                 }
3692                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3693                                 {
3694                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3695                                 }
3696                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3697                         }
3698                 }
3699                 if (isset($this->data['links'][$rel]))
3700                 {
3701                         return $this->data['links'][$rel];
3702                 }
3703                 else
3704                 {
3705                         return null;
3706                 }
3707         }
3708
3709         /**
3710          * @todo Add ability to prefer one type of content over another (in a media group).
3711          */
3712         function get_enclosure($key = 0, $prefer = null)
3713         {
3714                 $enclosures = $this->get_enclosures();
3715                 if (isset($enclosures[$key]))
3716                 {
3717                         return $enclosures[$key];
3718                 }
3719                 else
3720                 {
3721                         return null;
3722                 }
3723         }
3724
3725         /**
3726          * Grabs all available enclosures (podcasts, etc.)
3727          *
3728          * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3729          *
3730          * At this point, we're pretty much assuming that all enclosures for an item are the same content.  Anything else is too complicated to properly support.
3731          *
3732          * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3733          * @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).
3734          */
3735         function get_enclosures()
3736         {
3737                 if (!isset($this->data['enclosures']))
3738                 {
3739                         $this->data['enclosures'] = array();
3740
3741                         // Elements
3742                         $captions_parent = null;
3743                         $categories_parent = null;
3744                         $copyrights_parent = null;
3745                         $credits_parent = null;
3746                         $description_parent = null;
3747                         $duration_parent = null;
3748                         $hashes_parent = null;
3749                         $keywords_parent = null;
3750                         $player_parent = null;
3751                         $ratings_parent = null;
3752                         $restrictions_parent = null;
3753                         $thumbnails_parent = null;
3754                         $title_parent = null;
3755
3756                         // Let's do the channel and item-level ones first, and just re-use them if we need to.
3757                         $parent = $this->get_feed();
3758
3759                         // CAPTIONS
3760                         if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3761                         {
3762                                 foreach ($captions as $caption)
3763                                 {
3764                                         $caption_type = null;
3765                                         $caption_lang = null;
3766                                         $caption_startTime = null;
3767                                         $caption_endTime = null;
3768                                         $caption_text = null;
3769                                         if (isset($caption['attribs']['']['type']))
3770                                         {
3771                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3772                                         }
3773                                         if (isset($caption['attribs']['']['lang']))
3774                                         {
3775                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3776                                         }
3777                                         if (isset($caption['attribs']['']['start']))
3778                                         {
3779                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3780                                         }
3781                                         if (isset($caption['attribs']['']['end']))
3782                                         {
3783                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3784                                         }
3785                                         if (isset($caption['data']))
3786                                         {
3787                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3788                                         }
3789                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3790                                 }
3791                         }
3792                         elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3793                         {
3794                                 foreach ($captions as $caption)
3795                                 {
3796                                         $caption_type = null;
3797                                         $caption_lang = null;
3798                                         $caption_startTime = null;
3799                                         $caption_endTime = null;
3800                                         $caption_text = null;
3801                                         if (isset($caption['attribs']['']['type']))
3802                                         {
3803                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3804                                         }
3805                                         if (isset($caption['attribs']['']['lang']))
3806                                         {
3807                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3808                                         }
3809                                         if (isset($caption['attribs']['']['start']))
3810                                         {
3811                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3812                                         }
3813                                         if (isset($caption['attribs']['']['end']))
3814                                         {
3815                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3816                                         }
3817                                         if (isset($caption['data']))
3818                                         {
3819                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3820                                         }
3821                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3822                                 }
3823                         }
3824                         if (is_array($captions_parent))
3825                         {
3826                                 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3827                         }
3828
3829                         // CATEGORIES
3830                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3831                         {
3832                                 $term = null;
3833                                 $scheme = null;
3834                                 $label = null;
3835                                 if (isset($category['data']))
3836                                 {
3837                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3838                                 }
3839                                 if (isset($category['attribs']['']['scheme']))
3840                                 {
3841                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3842                                 }
3843                                 else
3844                                 {
3845                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3846                                 }
3847                                 if (isset($category['attribs']['']['label']))
3848                                 {
3849                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3850                                 }
3851                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3852                         }
3853                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3854                         {
3855                                 $term = null;
3856                                 $scheme = null;
3857                                 $label = null;
3858                                 if (isset($category['data']))
3859                                 {
3860                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3861                                 }
3862                                 if (isset($category['attribs']['']['scheme']))
3863                                 {
3864                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3865                                 }
3866                                 else
3867                                 {
3868                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3869                                 }
3870                                 if (isset($category['attribs']['']['label']))
3871                                 {
3872                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3873                                 }
3874                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3875                         }
3876                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3877                         {
3878                                 $term = null;
3879                                 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3880                                 $label = null;
3881                                 if (isset($category['attribs']['']['text']))
3882                                 {
3883                                         $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3884                                 }
3885                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3886
3887                                 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3888                                 {
3889                                         foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3890                                         {
3891                                                 if (isset($subcategory['attribs']['']['text']))
3892                                                 {
3893                                                         $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3894                                                 }
3895                                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3896                                         }
3897                                 }
3898                         }
3899                         if (is_array($categories_parent))
3900                         {
3901                                 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3902                         }
3903
3904                         // COPYRIGHT
3905                         if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3906                         {
3907                                 $copyright_url = null;
3908                                 $copyright_label = null;
3909                                 if (isset($copyright[0]['attribs']['']['url']))
3910                                 {
3911                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3912                                 }
3913                                 if (isset($copyright[0]['data']))
3914                                 {
3915                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3916                                 }
3917                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3918                         }
3919                         elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3920                         {
3921                                 $copyright_url = null;
3922                                 $copyright_label = null;
3923                                 if (isset($copyright[0]['attribs']['']['url']))
3924                                 {
3925                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3926                                 }
3927                                 if (isset($copyright[0]['data']))
3928                                 {
3929                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3930                                 }
3931                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3932                         }
3933
3934                         // CREDITS
3935                         if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3936                         {
3937                                 foreach ($credits as $credit)
3938                                 {
3939                                         $credit_role = null;
3940                                         $credit_scheme = null;
3941                                         $credit_name = null;
3942                                         if (isset($credit['attribs']['']['role']))
3943                                         {
3944                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3945                                         }
3946                                         if (isset($credit['attribs']['']['scheme']))
3947                                         {
3948                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3949                                         }
3950                                         else
3951                                         {
3952                                                 $credit_scheme = 'urn:ebu';
3953                                         }
3954                                         if (isset($credit['data']))
3955                                         {
3956                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3957                                         }
3958                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3959                                 }
3960                         }
3961                         elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3962                         {
3963                                 foreach ($credits as $credit)
3964                                 {
3965                                         $credit_role = null;
3966                                         $credit_scheme = null;
3967                                         $credit_name = null;
3968                                         if (isset($credit['attribs']['']['role']))
3969                                         {
3970                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3971                                         }
3972                                         if (isset($credit['attribs']['']['scheme']))
3973                                         {
3974                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3975                                         }
3976                                         else
3977                                         {
3978                                                 $credit_scheme = 'urn:ebu';
3979                                         }
3980                                         if (isset($credit['data']))
3981                                         {
3982                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3983                                         }
3984                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3985                                 }
3986                         }
3987                         if (is_array($credits_parent))
3988                         {
3989                                 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3990                         }
3991
3992                         // DESCRIPTION
3993                         if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3994                         {
3995                                 if (isset($description_parent[0]['data']))
3996                                 {
3997                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3998                                 }
3999                         }
4000                         elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4001                         {
4002                                 if (isset($description_parent[0]['data']))
4003                                 {
4004                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4005                                 }
4006                         }
4007
4008                         // DURATION
4009                         if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4010                         {
4011                                 $seconds = null;
4012                                 $minutes = null;
4013                                 $hours = null;
4014                                 if (isset($duration_parent[0]['data']))
4015                                 {
4016                                         $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4017                                         if (sizeof($temp) > 0)
4018                                         {
4019                                                 (int) $seconds = array_pop($temp);
4020                                         }
4021                                         if (sizeof($temp) > 0)
4022                                         {
4023                                                 (int) $minutes = array_pop($temp);
4024                                                 $seconds += $minutes * 60;
4025                                         }
4026                                         if (sizeof($temp) > 0)
4027                                         {
4028                                                 (int) $hours = array_pop($temp);
4029                                                 $seconds += $hours * 3600;
4030                                         }
4031                                         unset($temp);
4032                                         $duration_parent = $seconds;
4033                                 }
4034                         }
4035
4036                         // HASHES
4037                         if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4038                         {
4039                                 foreach ($hashes_iterator as $hash)
4040                                 {
4041                                         $value = null;
4042                                         $algo = null;
4043                                         if (isset($hash['data']))
4044                                         {
4045                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4046                                         }
4047                                         if (isset($hash['attribs']['']['algo']))
4048                                         {
4049                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4050                                         }
4051                                         else
4052                                         {
4053                                                 $algo = 'md5';
4054                                         }
4055                                         $hashes_parent[] = $algo.':'.$value;
4056                                 }
4057                         }
4058                         elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4059                         {
4060                                 foreach ($hashes_iterator as $hash)
4061                                 {
4062                                         $value = null;
4063                                         $algo = null;
4064                                         if (isset($hash['data']))
4065                                         {
4066                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4067                                         }
4068                                         if (isset($hash['attribs']['']['algo']))
4069                                         {
4070                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4071                                         }
4072                                         else
4073                                         {
4074                                                 $algo = 'md5';
4075                                         }
4076                                         $hashes_parent[] = $algo.':'.$value;
4077                                 }
4078                         }
4079                         if (is_array($hashes_parent))
4080                         {
4081                                 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4082                         }
4083
4084                         // KEYWORDS
4085                         if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4086                         {
4087                                 if (isset($keywords[0]['data']))
4088                                 {
4089                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4090                                         foreach ($temp as $word)
4091                                         {
4092                                                 $keywords_parent[] = trim($word);
4093                                         }
4094                                 }
4095                                 unset($temp);
4096                         }
4097                         elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4098                         {
4099                                 if (isset($keywords[0]['data']))
4100                                 {
4101                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4102                                         foreach ($temp as $word)
4103                                         {
4104                                                 $keywords_parent[] = trim($word);
4105                                         }
4106                                 }
4107                                 unset($temp);
4108                         }
4109                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4110                         {
4111                                 if (isset($keywords[0]['data']))
4112                                 {
4113                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4114                                         foreach ($temp as $word)
4115                                         {
4116                                                 $keywords_parent[] = trim($word);
4117                                         }
4118                                 }
4119                                 unset($temp);
4120                         }
4121                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4122                         {
4123                                 if (isset($keywords[0]['data']))
4124                                 {
4125                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4126                                         foreach ($temp as $word)
4127                                         {
4128                                                 $keywords_parent[] = trim($word);
4129                                         }
4130                                 }
4131                                 unset($temp);
4132                         }
4133                         if (is_array($keywords_parent))
4134                         {
4135                                 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4136                         }
4137
4138                         // PLAYER
4139                         if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4140                         {
4141                                 if (isset($player_parent[0]['attribs']['']['url']))
4142                                 {
4143                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4144                                 }
4145                         }
4146                         elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4147                         {
4148                                 if (isset($player_parent[0]['attribs']['']['url']))
4149                                 {
4150                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4151                                 }
4152                         }
4153
4154                         // RATINGS
4155                         if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4156                         {
4157                                 foreach ($ratings as $rating)
4158                                 {
4159                                         $rating_scheme = null;
4160                                         $rating_value = null;
4161                                         if (isset($rating['attribs']['']['scheme']))
4162                                         {
4163                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4164                                         }
4165                                         else
4166                                         {
4167                                                 $rating_scheme = 'urn:simple';
4168                                         }
4169                                         if (isset($rating['data']))
4170                                         {
4171                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4172                                         }
4173                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4174                                 }
4175                         }
4176                         elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4177                         {
4178                                 foreach ($ratings as $rating)
4179                                 {
4180                                         $rating_scheme = 'urn:itunes';
4181                                         $rating_value = null;
4182                                         if (isset($rating['data']))
4183                                         {
4184                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4185                                         }
4186                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4187                                 }
4188                         }
4189                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4190                         {
4191                                 foreach ($ratings as $rating)
4192                                 {
4193                                         $rating_scheme = null;
4194                                         $rating_value = null;
4195                                         if (isset($rating['attribs']['']['scheme']))
4196                                         {
4197                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4198                                         }
4199                                         else
4200                                         {
4201                                                 $rating_scheme = 'urn:simple';
4202                                         }
4203                                         if (isset($rating['data']))
4204                                         {
4205                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4206                                         }
4207                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4208                                 }
4209                         }
4210                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4211                         {
4212                                 foreach ($ratings as $rating)
4213                                 {
4214                                         $rating_scheme = 'urn:itunes';
4215                                         $rating_value = null;
4216                                         if (isset($rating['data']))
4217                                         {
4218                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4219                                         }
4220                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4221                                 }
4222                         }
4223                         if (is_array($ratings_parent))
4224                         {
4225                                 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4226                         }
4227
4228                         // RESTRICTIONS
4229                         if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4230                         {
4231                                 foreach ($restrictions as $restriction)
4232                                 {
4233                                         $restriction_relationship = null;
4234                                         $restriction_type = null;
4235                                         $restriction_value = null;
4236                                         if (isset($restriction['attribs']['']['relationship']))
4237                                         {
4238                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4239                                         }
4240                                         if (isset($restriction['attribs']['']['type']))
4241                                         {
4242                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4243                                         }
4244                                         if (isset($restriction['data']))
4245                                         {
4246                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4247                                         }
4248                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4249                                 }
4250                         }
4251                         elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4252                         {
4253                                 foreach ($restrictions as $restriction)
4254                                 {
4255                                         $restriction_relationship = 'allow';
4256                                         $restriction_type = null;
4257                                         $restriction_value = 'itunes';
4258                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4259                                         {
4260                                                 $restriction_relationship = 'deny';
4261                                         }
4262                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4263                                 }
4264                         }
4265                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4266                         {
4267                                 foreach ($restrictions as $restriction)
4268                                 {
4269                                         $restriction_relationship = null;
4270                                         $restriction_type = null;
4271                                         $restriction_value = null;
4272                                         if (isset($restriction['attribs']['']['relationship']))
4273                                         {
4274                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4275                                         }
4276                                         if (isset($restriction['attribs']['']['type']))
4277                                         {
4278                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4279                                         }
4280                                         if (isset($restriction['data']))
4281                                         {
4282                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4283                                         }
4284                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4285                                 }
4286                         }
4287                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4288                         {
4289                                 foreach ($restrictions as $restriction)
4290                                 {
4291                                         $restriction_relationship = 'allow';
4292                                         $restriction_type = null;
4293                                         $restriction_value = 'itunes';
4294                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4295                                         {
4296                                                 $restriction_relationship = 'deny';
4297                                         }
4298                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4299                                 }
4300                         }
4301                         if (is_array($restrictions_parent))
4302                         {
4303                                 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4304                         }
4305
4306                         // THUMBNAILS
4307                         if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4308                         {
4309                                 foreach ($thumbnails as $thumbnail)
4310                                 {
4311                                         if (isset($thumbnail['attribs']['']['url']))
4312                                         {
4313                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4314                                         }
4315                                 }
4316                         }
4317                         elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4318                         {
4319                                 foreach ($thumbnails as $thumbnail)
4320                                 {
4321                                         if (isset($thumbnail['attribs']['']['url']))
4322                                         {
4323                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4324                                         }
4325                                 }
4326                         }
4327
4328                         // TITLES
4329                         if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4330                         {
4331                                 if (isset($title_parent[0]['data']))
4332                                 {
4333                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4334                                 }
4335                         }
4336                         elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4337                         {
4338                                 if (isset($title_parent[0]['data']))
4339                                 {
4340                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4341                                 }
4342                         }
4343
4344                         // Clear the memory
4345                         unset($parent);
4346
4347                         // Attributes
4348                         $bitrate = null;
4349                         $channels = null;
4350                         $duration = null;
4351                         $expression = null;
4352                         $framerate = null;
4353                         $height = null;
4354                         $javascript = null;
4355                         $lang = null;
4356                         $length = null;
4357                         $medium = null;
4358                         $samplingrate = null;
4359                         $type = null;
4360                         $url = null;
4361                         $width = null;
4362
4363                         // Elements
4364                         $captions = null;
4365                         $categories = null;
4366                         $copyrights = null;
4367                         $credits = null;
4368                         $description = null;
4369                         $hashes = null;
4370                         $keywords = null;
4371                         $player = null;
4372                         $ratings = null;
4373                         $restrictions = null;
4374                         $thumbnails = null;
4375                         $title = null;
4376
4377                         // If we have media:group tags, loop through them.
4378                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4379                         {
4380                                 // If we have media:content tags, loop through them.
4381                                 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4382                                 {
4383                                         if (isset($content['attribs']['']['url']))
4384                                         {
4385                                                 // Attributes
4386                                                 $bitrate = null;
4387                                                 $channels = null;
4388                                                 $duration = null;
4389                                                 $expression = null;
4390                                                 $framerate = null;
4391                                                 $height = null;
4392                                                 $javascript = null;
4393                                                 $lang = null;
4394                                                 $length = null;
4395                                                 $medium = null;
4396                                                 $samplingrate = null;
4397                                                 $type = null;
4398                                                 $url = null;
4399                                                 $width = null;
4400
4401                                                 // Elements
4402                                                 $captions = null;
4403                                                 $categories = null;
4404                                                 $copyrights = null;
4405                                                 $credits = null;
4406                                                 $description = null;
4407                                                 $hashes = null;
4408                                                 $keywords = null;
4409                                                 $player = null;
4410                                                 $ratings = null;
4411                                                 $restrictions = null;
4412                                                 $thumbnails = null;
4413                                                 $title = null;
4414
4415                                                 // Start checking the attributes of media:content
4416                                                 if (isset($content['attribs']['']['bitrate']))
4417                                                 {
4418                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4419                                                 }
4420                                                 if (isset($content['attribs']['']['channels']))
4421                                                 {
4422                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4423                                                 }
4424                                                 if (isset($content['attribs']['']['duration']))
4425                                                 {
4426                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4427                                                 }
4428                                                 else
4429                                                 {
4430                                                         $duration = $duration_parent;
4431                                                 }
4432                                                 if (isset($content['attribs']['']['expression']))
4433                                                 {
4434                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4435                                                 }
4436                                                 if (isset($content['attribs']['']['framerate']))
4437                                                 {
4438                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4439                                                 }
4440                                                 if (isset($content['attribs']['']['height']))
4441                                                 {
4442                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4443                                                 }
4444                                                 if (isset($content['attribs']['']['lang']))
4445                                                 {
4446                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4447                                                 }
4448                                                 if (isset($content['attribs']['']['fileSize']))
4449                                                 {
4450                                                         $length = ceil($content['attribs']['']['fileSize']);
4451                                                 }
4452                                                 if (isset($content['attribs']['']['medium']))
4453                                                 {
4454                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4455                                                 }
4456                                                 if (isset($content['attribs']['']['samplingrate']))
4457                                                 {
4458                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4459                                                 }
4460                                                 if (isset($content['attribs']['']['type']))
4461                                                 {
4462                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4463                                                 }
4464                                                 if (isset($content['attribs']['']['width']))
4465                                                 {
4466                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4467                                                 }
4468                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4469
4470                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4471
4472                                                 // CAPTIONS
4473                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4474                                                 {
4475                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4476                                                         {
4477                                                                 $caption_type = null;
4478                                                                 $caption_lang = null;
4479                                                                 $caption_startTime = null;
4480                                                                 $caption_endTime = null;
4481                                                                 $caption_text = null;
4482                                                                 if (isset($caption['attribs']['']['type']))
4483                                                                 {
4484                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4485                                                                 }
4486                                                                 if (isset($caption['attribs']['']['lang']))
4487                                                                 {
4488                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4489                                                                 }
4490                                                                 if (isset($caption['attribs']['']['start']))
4491                                                                 {
4492                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4493                                                                 }
4494                                                                 if (isset($caption['attribs']['']['end']))
4495                                                                 {
4496                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4497                                                                 }
4498                                                                 if (isset($caption['data']))
4499                                                                 {
4500                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4501                                                                 }
4502                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4503                                                         }
4504                                                         if (is_array($captions))
4505                                                         {
4506                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4507                                                         }
4508                                                 }
4509                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4510                                                 {
4511                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4512                                                         {
4513                                                                 $caption_type = null;
4514                                                                 $caption_lang = null;
4515                                                                 $caption_startTime = null;
4516                                                                 $caption_endTime = null;
4517                                                                 $caption_text = null;
4518                                                                 if (isset($caption['attribs']['']['type']))
4519                                                                 {
4520                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4521                                                                 }
4522                                                                 if (isset($caption['attribs']['']['lang']))
4523                                                                 {
4524                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4525                                                                 }
4526                                                                 if (isset($caption['attribs']['']['start']))
4527                                                                 {
4528                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4529                                                                 }
4530                                                                 if (isset($caption['attribs']['']['end']))
4531                                                                 {
4532                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4533                                                                 }
4534                                                                 if (isset($caption['data']))
4535                                                                 {
4536                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4537                                                                 }
4538                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4539                                                         }
4540                                                         if (is_array($captions))
4541                                                         {
4542                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4543                                                         }
4544                                                 }
4545                                                 else
4546                                                 {
4547                                                         $captions = $captions_parent;
4548                                                 }
4549
4550                                                 // CATEGORIES
4551                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4552                                                 {
4553                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4554                                                         {
4555                                                                 $term = null;
4556                                                                 $scheme = null;
4557                                                                 $label = null;
4558                                                                 if (isset($category['data']))
4559                                                                 {
4560                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4561                                                                 }
4562                                                                 if (isset($category['attribs']['']['scheme']))
4563                                                                 {
4564                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4565                                                                 }
4566                                                                 else
4567                                                                 {
4568                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4569                                                                 }
4570                                                                 if (isset($category['attribs']['']['label']))
4571                                                                 {
4572                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4573                                                                 }
4574                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4575                                                         }
4576                                                 }
4577                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4578                                                 {
4579                                                         foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4580                                                         {
4581                                                                 $term = null;
4582                                                                 $scheme = null;
4583                                                                 $label = null;
4584                                                                 if (isset($category['data']))
4585                                                                 {
4586                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4587                                                                 }
4588                                                                 if (isset($category['attribs']['']['scheme']))
4589                                                                 {
4590                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4591                                                                 }
4592                                                                 else
4593                                                                 {
4594                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4595                                                                 }
4596                                                                 if (isset($category['attribs']['']['label']))
4597                                                                 {
4598                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4599                                                                 }
4600                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4601                                                         }
4602                                                 }
4603                                                 if (is_array($categories) && is_array($categories_parent))
4604                                                 {
4605                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4606                                                 }
4607                                                 elseif (is_array($categories))
4608                                                 {
4609                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
4610                                                 }
4611                                                 elseif (is_array($categories_parent))
4612                                                 {
4613                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4614                                                 }
4615
4616                                                 // COPYRIGHTS
4617                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4618                                                 {
4619                                                         $copyright_url = null;
4620                                                         $copyright_label = null;
4621                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4622                                                         {
4623                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4624                                                         }
4625                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4626                                                         {
4627                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4628                                                         }
4629                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4630                                                 }
4631                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4632                                                 {
4633                                                         $copyright_url = null;
4634                                                         $copyright_label = null;
4635                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4636                                                         {
4637                                                                 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4638                                                         }
4639                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4640                                                         {
4641                                                                 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4642                                                         }
4643                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4644                                                 }
4645                                                 else
4646                                                 {
4647                                                         $copyrights = $copyrights_parent;
4648                                                 }
4649
4650                                                 // CREDITS
4651                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4652                                                 {
4653                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4654                                                         {
4655                                                                 $credit_role = null;
4656                                                                 $credit_scheme = null;
4657                                                                 $credit_name = null;
4658                                                                 if (isset($credit['attribs']['']['role']))
4659                                                                 {
4660                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4661                                                                 }
4662                                                                 if (isset($credit['attribs']['']['scheme']))
4663                                                                 {
4664                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4665                                                                 }
4666                                                                 else
4667                                                                 {
4668                                                                         $credit_scheme = 'urn:ebu';
4669                                                                 }
4670                                                                 if (isset($credit['data']))
4671                                                                 {
4672                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4673                                                                 }
4674                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4675                                                         }
4676                                                         if (is_array($credits))
4677                                                         {
4678                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4679                                                         }
4680                                                 }
4681                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4682                                                 {
4683                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4684                                                         {
4685                                                                 $credit_role = null;
4686                                                                 $credit_scheme = null;
4687                                                                 $credit_name = null;
4688                                                                 if (isset($credit['attribs']['']['role']))
4689                                                                 {
4690                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4691                                                                 }
4692                                                                 if (isset($credit['attribs']['']['scheme']))
4693                                                                 {
4694                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4695                                                                 }
4696                                                                 else
4697                                                                 {
4698                                                                         $credit_scheme = 'urn:ebu';
4699                                                                 }
4700                                                                 if (isset($credit['data']))
4701                                                                 {
4702                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4703                                                                 }
4704                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4705                                                         }
4706                                                         if (is_array($credits))
4707                                                         {
4708                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4709                                                         }
4710                                                 }
4711                                                 else
4712                                                 {
4713                                                         $credits = $credits_parent;
4714                                                 }
4715
4716                                                 // DESCRIPTION
4717                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4718                                                 {
4719                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4720                                                 }
4721                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4722                                                 {
4723                                                         $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4724                                                 }
4725                                                 else
4726                                                 {
4727                                                         $description = $description_parent;
4728                                                 }
4729
4730                                                 // HASHES
4731                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4732                                                 {
4733                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4734                                                         {
4735                                                                 $value = null;
4736                                                                 $algo = null;
4737                                                                 if (isset($hash['data']))
4738                                                                 {
4739                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4740                                                                 }
4741                                                                 if (isset($hash['attribs']['']['algo']))
4742                                                                 {
4743                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4744                                                                 }
4745                                                                 else
4746                                                                 {
4747                                                                         $algo = 'md5';
4748                                                                 }
4749                                                                 $hashes[] = $algo.':'.$value;
4750                                                         }
4751                                                         if (is_array($hashes))
4752                                                         {
4753                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4754                                                         }
4755                                                 }
4756                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4757                                                 {
4758                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4759                                                         {
4760                                                                 $value = null;
4761                                                                 $algo = null;
4762                                                                 if (isset($hash['data']))
4763                                                                 {
4764                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4765                                                                 }
4766                                                                 if (isset($hash['attribs']['']['algo']))
4767                                                                 {
4768                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4769                                                                 }
4770                                                                 else
4771                                                                 {
4772                                                                         $algo = 'md5';
4773                                                                 }
4774                                                                 $hashes[] = $algo.':'.$value;
4775                                                         }
4776                                                         if (is_array($hashes))
4777                                                         {
4778                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4779                                                         }
4780                                                 }
4781                                                 else
4782                                                 {
4783                                                         $hashes = $hashes_parent;
4784                                                 }
4785
4786                                                 // KEYWORDS
4787                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4788                                                 {
4789                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4790                                                         {
4791                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4792                                                                 foreach ($temp as $word)
4793                                                                 {
4794                                                                         $keywords[] = trim($word);
4795                                                                 }
4796                                                                 unset($temp);
4797                                                         }
4798                                                         if (is_array($keywords))
4799                                                         {
4800                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4801                                                         }
4802                                                 }
4803                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4804                                                 {
4805                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4806                                                         {
4807                                                                 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4808                                                                 foreach ($temp as $word)
4809                                                                 {
4810                                                                         $keywords[] = trim($word);
4811                                                                 }
4812                                                                 unset($temp);
4813                                                         }
4814                                                         if (is_array($keywords))
4815                                                         {
4816                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4817                                                         }
4818                                                 }
4819                                                 else
4820                                                 {
4821                                                         $keywords = $keywords_parent;
4822                                                 }
4823
4824                                                 // PLAYER
4825                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4826                                                 {
4827                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4828                                                 }
4829                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4830                                                 {
4831                                                         $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4832                                                 }
4833                                                 else
4834                                                 {
4835                                                         $player = $player_parent;
4836                                                 }
4837
4838                                                 // RATINGS
4839                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4840                                                 {
4841                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4842                                                         {
4843                                                                 $rating_scheme = null;
4844                                                                 $rating_value = null;
4845                                                                 if (isset($rating['attribs']['']['scheme']))
4846                                                                 {
4847                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4848                                                                 }
4849                                                                 else
4850                                                                 {
4851                                                                         $rating_scheme = 'urn:simple';
4852                                                                 }
4853                                                                 if (isset($rating['data']))
4854                                                                 {
4855                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4856                                                                 }
4857                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4858                                                         }
4859                                                         if (is_array($ratings))
4860                                                         {
4861                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4862                                                         }
4863                                                 }
4864                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4865                                                 {
4866                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4867                                                         {
4868                                                                 $rating_scheme = null;
4869                                                                 $rating_value = null;
4870                                                                 if (isset($rating['attribs']['']['scheme']))
4871                                                                 {
4872                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4873                                                                 }
4874                                                                 else
4875                                                                 {
4876                                                                         $rating_scheme = 'urn:simple';
4877                                                                 }
4878                                                                 if (isset($rating['data']))
4879                                                                 {
4880                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4881                                                                 }
4882                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4883                                                         }
4884                                                         if (is_array($ratings))
4885                                                         {
4886                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4887                                                         }
4888                                                 }
4889                                                 else
4890                                                 {
4891                                                         $ratings = $ratings_parent;
4892                                                 }
4893
4894                                                 // RESTRICTIONS
4895                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4896                                                 {
4897                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4898                                                         {
4899                                                                 $restriction_relationship = null;
4900                                                                 $restriction_type = null;
4901                                                                 $restriction_value = null;
4902                                                                 if (isset($restriction['attribs']['']['relationship']))
4903                                                                 {
4904                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4905                                                                 }
4906                                                                 if (isset($restriction['attribs']['']['type']))
4907                                                                 {
4908                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4909                                                                 }
4910                                                                 if (isset($restriction['data']))
4911                                                                 {
4912                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4913                                                                 }
4914                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4915                                                         }
4916                                                         if (is_array($restrictions))
4917                                                         {
4918                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4919                                                         }
4920                                                 }
4921                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4922                                                 {
4923                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4924                                                         {
4925                                                                 $restriction_relationship = null;
4926                                                                 $restriction_type = null;
4927                                                                 $restriction_value = null;
4928                                                                 if (isset($restriction['attribs']['']['relationship']))
4929                                                                 {
4930                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4931                                                                 }
4932                                                                 if (isset($restriction['attribs']['']['type']))
4933                                                                 {
4934                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4935                                                                 }
4936                                                                 if (isset($restriction['data']))
4937                                                                 {
4938                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4939                                                                 }
4940                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4941                                                         }
4942                                                         if (is_array($restrictions))
4943                                                         {
4944                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4945                                                         }
4946                                                 }
4947                                                 else
4948                                                 {
4949                                                         $restrictions = $restrictions_parent;
4950                                                 }
4951
4952                                                 // THUMBNAILS
4953                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4954                                                 {
4955                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4956                                                         {
4957                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4958                                                         }
4959                                                         if (is_array($thumbnails))
4960                                                         {
4961                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4962                                                         }
4963                                                 }
4964                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4965                                                 {
4966                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4967                                                         {
4968                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4969                                                         }
4970                                                         if (is_array($thumbnails))
4971                                                         {
4972                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4973                                                         }
4974                                                 }
4975                                                 else
4976                                                 {
4977                                                         $thumbnails = $thumbnails_parent;
4978                                                 }
4979
4980                                                 // TITLES
4981                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4982                                                 {
4983                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4984                                                 }
4985                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4986                                                 {
4987                                                         $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4988                                                 }
4989                                                 else
4990                                                 {
4991                                                         $title = $title_parent;
4992                                                 }
4993
4994                                                 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
4995                                         }
4996                                 }
4997                         }
4998
4999                         // If we have standalone media:content tags, loop through them.
5000                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5001                         {
5002                                 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5003                                 {
5004                                         if (isset($content['attribs']['']['url']))
5005                                         {
5006                                                 // Attributes
5007                                                 $bitrate = null;
5008                                                 $channels = null;
5009                                                 $duration = null;
5010                                                 $expression = null;
5011                                                 $framerate = null;
5012                                                 $height = null;
5013                                                 $javascript = null;
5014                                                 $lang = null;
5015                                                 $length = null;
5016                                                 $medium = null;
5017                                                 $samplingrate = null;
5018                                                 $type = null;
5019                                                 $url = null;
5020                                                 $width = null;
5021
5022                                                 // Elements
5023                                                 $captions = null;
5024                                                 $categories = null;
5025                                                 $copyrights = null;
5026                                                 $credits = null;
5027                                                 $description = null;
5028                                                 $hashes = null;
5029                                                 $keywords = null;
5030                                                 $player = null;
5031                                                 $ratings = null;
5032                                                 $restrictions = null;
5033                                                 $thumbnails = null;
5034                                                 $title = null;
5035
5036                                                 // Start checking the attributes of media:content
5037                                                 if (isset($content['attribs']['']['bitrate']))
5038                                                 {
5039                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5040                                                 }
5041                                                 if (isset($content['attribs']['']['channels']))
5042                                                 {
5043                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5044                                                 }
5045                                                 if (isset($content['attribs']['']['duration']))
5046                                                 {
5047                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5048                                                 }
5049                                                 else
5050                                                 {
5051                                                         $duration = $duration_parent;
5052                                                 }
5053                                                 if (isset($content['attribs']['']['expression']))
5054                                                 {
5055                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5056                                                 }
5057                                                 if (isset($content['attribs']['']['framerate']))
5058                                                 {
5059                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5060                                                 }
5061                                                 if (isset($content['attribs']['']['height']))
5062                                                 {
5063                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5064                                                 }
5065                                                 if (isset($content['attribs']['']['lang']))
5066                                                 {
5067                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5068                                                 }
5069                                                 if (isset($content['attribs']['']['fileSize']))
5070                                                 {
5071                                                         $length = ceil($content['attribs']['']['fileSize']);
5072                                                 }
5073                                                 if (isset($content['attribs']['']['medium']))
5074                                                 {
5075                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5076                                                 }
5077                                                 if (isset($content['attribs']['']['samplingrate']))
5078                                                 {
5079                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5080                                                 }
5081                                                 if (isset($content['attribs']['']['type']))
5082                                                 {
5083                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5084                                                 }
5085                                                 if (isset($content['attribs']['']['width']))
5086                                                 {
5087                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5088                                                 }
5089                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5090
5091                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5092
5093                                                 // CAPTIONS
5094                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5095                                                 {
5096                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5097                                                         {
5098                                                                 $caption_type = null;
5099                                                                 $caption_lang = null;
5100                                                                 $caption_startTime = null;
5101                                                                 $caption_endTime = null;
5102                                                                 $caption_text = null;
5103                                                                 if (isset($caption['attribs']['']['type']))
5104                                                                 {
5105                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5106                                                                 }
5107                                                                 if (isset($caption['attribs']['']['lang']))
5108                                                                 {
5109                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5110                                                                 }
5111                                                                 if (isset($caption['attribs']['']['start']))
5112                                                                 {
5113                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5114                                                                 }
5115                                                                 if (isset($caption['attribs']['']['end']))
5116                                                                 {
5117                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5118                                                                 }
5119                                                                 if (isset($caption['data']))
5120                                                                 {
5121                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5122                                                                 }
5123                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5124                                                         }
5125                                                         if (is_array($captions))
5126                                                         {
5127                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
5128                                                         }
5129                                                 }
5130                                                 else
5131                                                 {
5132                                                         $captions = $captions_parent;
5133                                                 }
5134
5135                                                 // CATEGORIES
5136                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5137                                                 {
5138                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5139                                                         {
5140                                                                 $term = null;
5141                                                                 $scheme = null;
5142                                                                 $label = null;
5143                                                                 if (isset($category['data']))
5144                                                                 {
5145                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5146                                                                 }
5147                                                                 if (isset($category['attribs']['']['scheme']))
5148                                                                 {
5149                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5150                                                                 }
5151                                                                 else
5152                                                                 {
5153                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
5154                                                                 }
5155                                                                 if (isset($category['attribs']['']['label']))
5156                                                                 {
5157                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5158                                                                 }
5159                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5160                                                         }
5161                                                 }
5162                                                 if (is_array($categories) && is_array($categories_parent))
5163                                                 {
5164                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5165                                                 }
5166                                                 elseif (is_array($categories))
5167                                                 {
5168                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
5169                                                 }
5170                                                 elseif (is_array($categories_parent))
5171                                                 {
5172                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5173                                                 }
5174                                                 else
5175                                                 {
5176                                                         $categories = null;
5177                                                 }
5178
5179                                                 // COPYRIGHTS
5180                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5181                                                 {
5182                                                         $copyright_url = null;
5183                                                         $copyright_label = null;
5184                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5185                                                         {
5186                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5187                                                         }
5188                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5189                                                         {
5190                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5191                                                         }
5192                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5193                                                 }
5194                                                 else
5195                                                 {
5196                                                         $copyrights = $copyrights_parent;
5197                                                 }
5198
5199                                                 // CREDITS
5200                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5201                                                 {
5202                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5203                                                         {
5204                                                                 $credit_role = null;
5205                                                                 $credit_scheme = null;
5206                                                                 $credit_name = null;
5207                                                                 if (isset($credit['attribs']['']['role']))
5208                                                                 {
5209                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5210                                                                 }
5211                                                                 if (isset($credit['attribs']['']['scheme']))
5212                                                                 {
5213                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5214                                                                 }
5215                                                                 else
5216                                                                 {
5217                                                                         $credit_scheme = 'urn:ebu';
5218                                                                 }
5219                                                                 if (isset($credit['data']))
5220                                                                 {
5221                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5222                                                                 }
5223                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5224                                                         }
5225                                                         if (is_array($credits))
5226                                                         {
5227                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
5228                                                         }
5229                                                 }
5230                                                 else
5231                                                 {
5232                                                         $credits = $credits_parent;
5233                                                 }
5234
5235                                                 // DESCRIPTION
5236                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5237                                                 {
5238                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5239                                                 }
5240                                                 else
5241                                                 {
5242                                                         $description = $description_parent;
5243                                                 }
5244
5245                                                 // HASHES
5246                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5247                                                 {
5248                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5249                                                         {
5250                                                                 $value = null;
5251                                                                 $algo = null;
5252                                                                 if (isset($hash['data']))
5253                                                                 {
5254                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5255                                                                 }
5256                                                                 if (isset($hash['attribs']['']['algo']))
5257                                                                 {
5258                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5259                                                                 }
5260                                                                 else
5261                                                                 {
5262                                                                         $algo = 'md5';
5263                                                                 }
5264                                                                 $hashes[] = $algo.':'.$value;
5265                                                         }
5266                                                         if (is_array($hashes))
5267                                                         {
5268                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5269                                                         }
5270                                                 }
5271                                                 else
5272                                                 {
5273                                                         $hashes = $hashes_parent;
5274                                                 }
5275
5276                                                 // KEYWORDS
5277                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5278                                                 {
5279                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5280                                                         {
5281                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5282                                                                 foreach ($temp as $word)
5283                                                                 {
5284                                                                         $keywords[] = trim($word);
5285                                                                 }
5286                                                                 unset($temp);
5287                                                         }
5288                                                         if (is_array($keywords))
5289                                                         {
5290                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5291                                                         }
5292                                                 }
5293                                                 else
5294                                                 {
5295                                                         $keywords = $keywords_parent;
5296                                                 }
5297
5298                                                 // PLAYER
5299                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5300                                                 {
5301                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5302                                                 }
5303                                                 else
5304                                                 {
5305                                                         $player = $player_parent;
5306                                                 }
5307
5308                                                 // RATINGS
5309                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5310                                                 {
5311                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5312                                                         {
5313                                                                 $rating_scheme = null;
5314                                                                 $rating_value = null;
5315                                                                 if (isset($rating['attribs']['']['scheme']))
5316                                                                 {
5317                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5318                                                                 }
5319                                                                 else
5320                                                                 {
5321                                                                         $rating_scheme = 'urn:simple';
5322                                                                 }
5323                                                                 if (isset($rating['data']))
5324                                                                 {
5325                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5326                                                                 }
5327                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5328                                                         }
5329                                                         if (is_array($ratings))
5330                                                         {
5331                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5332                                                         }
5333                                                 }
5334                                                 else
5335                                                 {
5336                                                         $ratings = $ratings_parent;
5337                                                 }
5338
5339                                                 // RESTRICTIONS
5340                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5341                                                 {
5342                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5343                                                         {
5344                                                                 $restriction_relationship = null;
5345                                                                 $restriction_type = null;
5346                                                                 $restriction_value = null;
5347                                                                 if (isset($restriction['attribs']['']['relationship']))
5348                                                                 {
5349                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5350                                                                 }
5351                                                                 if (isset($restriction['attribs']['']['type']))
5352                                                                 {
5353                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5354                                                                 }
5355                                                                 if (isset($restriction['data']))
5356                                                                 {
5357                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5358                                                                 }
5359                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5360                                                         }
5361                                                         if (is_array($restrictions))
5362                                                         {
5363                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5364                                                         }
5365                                                 }
5366                                                 else
5367                                                 {
5368                                                         $restrictions = $restrictions_parent;
5369                                                 }
5370
5371                                                 // THUMBNAILS
5372                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5373                                                 {
5374                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5375                                                         {
5376                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5377                                                         }
5378                                                         if (is_array($thumbnails))
5379                                                         {
5380                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5381                                                         }
5382                                                 }
5383                                                 else
5384                                                 {
5385                                                         $thumbnails = $thumbnails_parent;
5386                                                 }
5387
5388                                                 // TITLES
5389                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5390                                                 {
5391                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5392                                                 }
5393                                                 else
5394                                                 {
5395                                                         $title = $title_parent;
5396                                                 }
5397
5398                                                 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
5399                                         }
5400                                 }
5401                         }
5402
5403                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5404                         {
5405                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5406                                 {
5407                                         // Attributes
5408                                         $bitrate = null;
5409                                         $channels = null;
5410                                         $duration = null;
5411                                         $expression = null;
5412                                         $framerate = null;
5413                                         $height = null;
5414                                         $javascript = null;
5415                                         $lang = null;
5416                                         $length = null;
5417                                         $medium = null;
5418                                         $samplingrate = null;
5419                                         $type = null;
5420                                         $url = null;
5421                                         $width = null;
5422
5423                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5424                                         if (isset($link['attribs']['']['type']))
5425                                         {
5426                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5427                                         }
5428                                         if (isset($link['attribs']['']['length']))
5429                                         {
5430                                                 $length = ceil($link['attribs']['']['length']);
5431                                         }
5432
5433                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5434                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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);
5435                                 }
5436                         }
5437
5438                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5439                         {
5440                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5441                                 {
5442                                         // Attributes
5443                                         $bitrate = null;
5444                                         $channels = null;
5445                                         $duration = null;
5446                                         $expression = null;
5447                                         $framerate = null;
5448                                         $height = null;
5449                                         $javascript = null;
5450                                         $lang = null;
5451                                         $length = null;
5452                                         $medium = null;
5453                                         $samplingrate = null;
5454                                         $type = null;
5455                                         $url = null;
5456                                         $width = null;
5457
5458                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5459                                         if (isset($link['attribs']['']['type']))
5460                                         {
5461                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5462                                         }
5463                                         if (isset($link['attribs']['']['length']))
5464                                         {
5465                                                 $length = ceil($link['attribs']['']['length']);
5466                                         }
5467
5468                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5469                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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);
5470                                 }
5471                         }
5472
5473                         if ($enclosure = $this->get_item_tags('', 'enclosure'))
5474                         {
5475                                 if (isset($enclosure[0]['attribs']['']['url']))
5476                                 {
5477                                         // Attributes
5478                                         $bitrate = null;
5479                                         $channels = null;
5480                                         $duration = null;
5481                                         $expression = null;
5482                                         $framerate = null;
5483                                         $height = null;
5484                                         $javascript = null;
5485                                         $lang = null;
5486                                         $length = null;
5487                                         $medium = null;
5488                                         $samplingrate = null;
5489                                         $type = null;
5490                                         $url = null;
5491                                         $width = null;
5492
5493                                         $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5494                                         if (isset($enclosure[0]['attribs']['']['type']))
5495                                         {
5496                                                 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5497                                         }
5498                                         if (isset($enclosure[0]['attribs']['']['length']))
5499                                         {
5500                                                 $length = ceil($enclosure[0]['attribs']['']['length']);
5501                                         }
5502
5503                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5504                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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);
5505                                 }
5506                         }
5507
5508                         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))
5509                         {
5510                                 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5511                                 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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);
5512                         }
5513
5514                         $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5515                 }
5516                 if (!empty($this->data['enclosures']))
5517                 {
5518                         return $this->data['enclosures'];
5519                 }
5520                 else
5521                 {
5522                         return null;
5523                 }
5524         }
5525
5526         function get_latitude()
5527         {
5528                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5529                 {
5530                         return (float) $return[0]['data'];
5531                 }
5532                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5533                 {
5534                         return (float) $match[1];
5535                 }
5536                 else
5537                 {
5538                         return null;
5539                 }
5540         }
5541
5542         function get_longitude()
5543         {
5544                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5545                 {
5546                         return (float) $return[0]['data'];
5547                 }
5548                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5549                 {
5550                         return (float) $return[0]['data'];
5551                 }
5552                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5553                 {
5554                         return (float) $match[2];
5555                 }
5556                 else
5557                 {
5558                         return null;
5559                 }
5560         }
5561
5562         function get_source()
5563         {
5564                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5565                 {
5566                         return new $this->feed->source_class($this, $return[0]);
5567                 }
5568                 else
5569                 {
5570                         return null;
5571                 }
5572         }
5573
5574         /**
5575          * Creates the add_to_* methods' return data
5576          *
5577          * @access private
5578          * @param string $item_url String to prefix to the item permalink
5579          * @param string $title_url String to prefix to the item title
5580          * (and suffix to the item permalink)
5581          * @return mixed URL if feed exists, false otherwise
5582          */
5583         function add_to_service($item_url, $title_url = null, $summary_url = null)
5584         {
5585                 if ($this->get_permalink() !== null)
5586                 {
5587                         $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5588                         if ($title_url !== null && $this->get_title() !== null)
5589                         {
5590                                 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5591                         }
5592                         if ($summary_url !== null && $this->get_description() !== null)
5593                         {
5594                                 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5595                         }
5596                         return $return;
5597                 }
5598                 else
5599                 {
5600                         return null;
5601                 }
5602         }
5603
5604         function add_to_blinklist()
5605         {
5606                 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5607         }
5608
5609         function add_to_blogmarks()
5610         {
5611                 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5612         }
5613
5614         function add_to_delicious()
5615         {
5616                 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5617         }
5618
5619         function add_to_digg()
5620         {
5621                 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5622         }
5623
5624         function add_to_furl()
5625         {
5626                 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5627         }
5628
5629         function add_to_magnolia()
5630         {
5631                 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5632         }
5633
5634         function add_to_myweb20()
5635         {
5636                 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5637         }
5638
5639         function add_to_newsvine()
5640         {
5641                 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5642         }
5643
5644         function add_to_reddit()
5645         {
5646                 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5647         }
5648
5649         function add_to_segnalo()
5650         {
5651                 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5652         }
5653
5654         function add_to_simpy()
5655         {
5656                 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5657         }
5658
5659         function add_to_spurl()
5660         {
5661                 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5662         }
5663
5664         function add_to_wists()
5665         {
5666                 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5667         }
5668
5669         function search_technorati()
5670         {
5671                 return $this->add_to_service('http://www.technorati.com/search/');
5672         }
5673 }
5674
5675 class SimplePie_Source
5676 {
5677         var $item;
5678         var $data = array();
5679
5680         function SimplePie_Source($item, $data)
5681         {
5682                 $this->item = $item;
5683                 $this->data = $data;
5684         }
5685
5686         function __toString()
5687         {
5688                 return md5(serialize($this->data));
5689         }
5690
5691         function get_source_tags($namespace, $tag)
5692         {
5693                 if (isset($this->data['child'][$namespace][$tag]))
5694                 {
5695                         return $this->data['child'][$namespace][$tag];
5696                 }
5697                 else
5698                 {
5699                         return null;
5700                 }
5701         }
5702
5703         function get_base($element = array())
5704         {
5705                 return $this->item->get_base($element);
5706         }
5707
5708         function sanitize($data, $type, $base = '')
5709         {
5710                 return $this->item->sanitize($data, $type, $base);
5711         }
5712
5713         function get_item()
5714         {
5715                 return $this->item;
5716         }
5717
5718         function get_title()
5719         {
5720                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5721                 {
5722                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5723                 }
5724                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5725                 {
5726                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5727                 }
5728                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5729                 {
5730                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5731                 }
5732                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5733                 {
5734                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5735                 }
5736                 elseif ($return = $this->get_source_tags('', 'title'))
5737                 {
5738                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5739                 }
5740                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5741                 {
5742                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5743                 }
5744                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5745                 {
5746                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5747                 }
5748                 else
5749                 {
5750                         return null;
5751                 }
5752         }
5753
5754         function get_category($key = 0)
5755         {
5756                 $categories = $this->get_categories();
5757                 if (isset($categories[$key]))
5758                 {
5759                         return $categories[$key];
5760                 }
5761                 else
5762                 {
5763                         return null;
5764                 }
5765         }
5766
5767         function get_categories()
5768         {
5769                 $categories = array();
5770
5771                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5772                 {
5773                         $term = null;
5774                         $scheme = null;
5775                         $label = null;
5776                         if (isset($category['attribs']['']['term']))
5777                         {
5778                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5779                         }
5780                         if (isset($category['attribs']['']['scheme']))
5781                         {
5782                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5783                         }
5784                         if (isset($category['attribs']['']['label']))
5785                         {
5786                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5787                         }
5788                         $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5789                 }
5790                 foreach ((array) $this->get_source_tags('', 'category') as $category)
5791                 {
5792                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5793                 }
5794                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5795                 {
5796                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5797                 }
5798                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5799                 {
5800                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5801                 }
5802
5803                 if (!empty($categories))
5804                 {
5805                         return SimplePie_Misc::array_unique($categories);
5806                 }
5807                 else
5808                 {
5809                         return null;
5810                 }
5811         }
5812
5813         function get_author($key = 0)
5814         {
5815                 $authors = $this->get_authors();
5816                 if (isset($authors[$key]))
5817                 {
5818                         return $authors[$key];
5819                 }
5820                 else
5821                 {
5822                         return null;
5823                 }
5824         }
5825
5826         function get_authors()
5827         {
5828                 $authors = array();
5829                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5830                 {
5831                         $name = null;
5832                         $uri = null;
5833                         $email = null;
5834                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5835                         {
5836                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5837                         }
5838                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5839                         {
5840                                 $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]));
5841                         }
5842                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5843                         {
5844                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5845                         }
5846                         if ($name !== null || $email !== null || $uri !== null)
5847                         {
5848                                 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5849                         }
5850                 }
5851                 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5852                 {
5853                         $name = null;
5854                         $url = null;
5855                         $email = null;
5856                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5857                         {
5858                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5859                         }
5860                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5861                         {
5862                                 $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]));
5863                         }
5864                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5865                         {
5866                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5867                         }
5868                         if ($name !== null || $email !== null || $url !== null)
5869                         {
5870                                 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5871                         }
5872                 }
5873                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5874                 {
5875                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5876                 }
5877                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5878                 {
5879                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5880                 }
5881                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5882                 {
5883                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5884                 }
5885
5886                 if (!empty($authors))
5887                 {
5888                         return SimplePie_Misc::array_unique($authors);
5889                 }
5890                 else
5891                 {
5892                         return null;
5893                 }
5894         }
5895
5896         function get_contributor($key = 0)
5897         {
5898                 $contributors = $this->get_contributors();
5899                 if (isset($contributors[$key]))
5900                 {
5901                         return $contributors[$key];
5902                 }
5903                 else
5904                 {
5905                         return null;
5906                 }
5907         }
5908
5909         function get_contributors()
5910         {
5911                 $contributors = array();
5912                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5913                 {
5914                         $name = null;
5915                         $uri = null;
5916                         $email = null;
5917                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5918                         {
5919                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5920                         }
5921                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5922                         {
5923                                 $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]));
5924                         }
5925                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5926                         {
5927                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5928                         }
5929                         if ($name !== null || $email !== null || $uri !== null)
5930                         {
5931                                 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5932                         }
5933                 }
5934                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5935                 {
5936                         $name = null;
5937                         $url = null;
5938                         $email = null;
5939                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5940                         {
5941                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5942                         }
5943                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5944                         {
5945                                 $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]));
5946                         }
5947                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5948                         {
5949                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5950                         }
5951                         if ($name !== null || $email !== null || $url !== null)
5952                         {
5953                                 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5954                         }
5955                 }
5956
5957                 if (!empty($contributors))
5958                 {
5959                         return SimplePie_Misc::array_unique($contributors);
5960                 }
5961                 else
5962                 {
5963                         return null;
5964                 }
5965         }
5966
5967         function get_link($key = 0, $rel = 'alternate')
5968         {
5969                 $links = $this->get_links($rel);
5970                 if (isset($links[$key]))
5971                 {
5972                         return $links[$key];
5973                 }
5974                 else
5975                 {
5976                         return null;
5977                 }
5978         }
5979
5980         /**
5981          * Added for parity between the parent-level and the item/entry-level.
5982          */
5983         function get_permalink()
5984         {
5985                 return $this->get_link(0);
5986         }
5987
5988         function get_links($rel = 'alternate')
5989         {
5990                 if (!isset($this->data['links']))
5991                 {
5992                         $this->data['links'] = array();
5993                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5994                         {
5995                                 foreach ($links as $link)
5996                                 {
5997                                         if (isset($link['attribs']['']['href']))
5998                                         {
5999                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6000                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6001                                         }
6002                                 }
6003                         }
6004                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6005                         {
6006                                 foreach ($links as $link)
6007                                 {
6008                                         if (isset($link['attribs']['']['href']))
6009                                         {
6010                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6011                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6012
6013                                         }
6014                                 }
6015                         }
6016                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6017                         {
6018                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6019                         }
6020                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6021                         {
6022                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6023                         }
6024                         if ($links = $this->get_source_tags('', 'link'))
6025                         {
6026                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6027                         }
6028
6029                         $keys = array_keys($this->data['links']);
6030                         foreach ($keys as $key)
6031                         {
6032                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
6033                                 {
6034                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6035                                         {
6036                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6037                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6038                                         }
6039                                         else
6040                                         {
6041                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6042                                         }
6043                                 }
6044                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6045                                 {
6046                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6047                                 }
6048                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6049                         }
6050                 }
6051
6052                 if (isset($this->data['links'][$rel]))
6053                 {
6054                         return $this->data['links'][$rel];
6055                 }
6056                 else
6057                 {
6058                         return null;
6059                 }
6060         }
6061
6062         function get_description()
6063         {
6064                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6065                 {
6066                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6067                 }
6068                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6069                 {
6070                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6071                 }
6072                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6073                 {
6074                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6075                 }
6076                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6077                 {
6078                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6079                 }
6080                 elseif ($return = $this->get_source_tags('', 'description'))
6081                 {
6082                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6083                 }
6084                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6085                 {
6086                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6087                 }
6088                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6089                 {
6090                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6091                 }
6092                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6093                 {
6094                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6095                 }
6096                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6097                 {
6098                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6099                 }
6100                 else
6101                 {
6102                         return null;
6103                 }
6104         }
6105
6106         function get_copyright()
6107         {
6108                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6109                 {
6110                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6111                 }
6112                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6113                 {
6114                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6115                 }
6116                 elseif ($return = $this->get_source_tags('', 'copyright'))
6117                 {
6118                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6119                 }
6120                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6121                 {
6122                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6123                 }
6124                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6125                 {
6126                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6127                 }
6128                 else
6129                 {
6130                         return null;
6131                 }
6132         }
6133
6134         function get_language()
6135         {
6136                 if ($return = $this->get_source_tags('', 'language'))
6137                 {
6138                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6139                 }
6140                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6141                 {
6142                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6143                 }
6144                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6145                 {
6146                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6147                 }
6148                 elseif (isset($this->data['xml_lang']))
6149                 {
6150                         return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6151                 }
6152                 else
6153                 {
6154                         return null;
6155                 }
6156         }
6157
6158         function get_latitude()
6159         {
6160                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6161                 {
6162                         return (float) $return[0]['data'];
6163                 }
6164                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6165                 {
6166                         return (float) $match[1];
6167                 }
6168                 else
6169                 {
6170                         return null;
6171                 }
6172         }
6173
6174         function get_longitude()
6175         {
6176                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6177                 {
6178                         return (float) $return[0]['data'];
6179                 }
6180                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6181                 {
6182                         return (float) $return[0]['data'];
6183                 }
6184                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6185                 {
6186                         return (float) $match[2];
6187                 }
6188                 else
6189                 {
6190                         return null;
6191                 }
6192         }
6193
6194         function get_image_url()
6195         {
6196                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6197                 {
6198                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6199                 }
6200                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6201                 {
6202                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6203                 }
6204                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6205                 {
6206                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6207                 }
6208                 else
6209                 {
6210                         return null;
6211                 }
6212         }
6213 }
6214
6215 class SimplePie_Author
6216 {
6217         var $name;
6218         var $link;
6219         var $email;
6220
6221         // Constructor, used to input the data
6222         function SimplePie_Author($name = null, $link = null, $email = null)
6223         {
6224                 $this->name = $name;
6225                 $this->link = $link;
6226                 $this->email = $email;
6227         }
6228
6229         function __toString()
6230         {
6231                 // There is no $this->data here
6232                 return md5(serialize($this));
6233         }
6234
6235         function get_name()
6236         {
6237                 if ($this->name !== null)
6238                 {
6239                         return $this->name;
6240                 }
6241                 else
6242                 {
6243                         return null;
6244                 }
6245         }
6246
6247         function get_link()
6248         {
6249                 if ($this->link !== null)
6250                 {
6251                         return $this->link;
6252                 }
6253                 else
6254                 {
6255                         return null;
6256                 }
6257         }
6258
6259         function get_email()
6260         {
6261                 if ($this->email !== null)
6262                 {
6263                         return $this->email;
6264                 }
6265                 else
6266                 {
6267                         return null;
6268                 }
6269         }
6270 }
6271
6272 class SimplePie_Category
6273 {
6274         var $term;
6275         var $scheme;
6276         var $label;
6277
6278         // Constructor, used to input the data
6279         function SimplePie_Category($term = null, $scheme = null, $label = null)
6280         {
6281                 $this->term = $term;
6282                 $this->scheme = $scheme;
6283                 $this->label = $label;
6284         }
6285
6286         function __toString()
6287         {
6288                 // There is no $this->data here
6289                 return md5(serialize($this));
6290         }
6291
6292         function get_term()
6293         {
6294                 if ($this->term !== null)
6295                 {
6296                         return $this->term;
6297                 }
6298                 else
6299                 {
6300                         return null;
6301                 }
6302         }
6303
6304         function get_scheme()
6305         {
6306                 if ($this->scheme !== null)
6307                 {
6308                         return $this->scheme;
6309                 }
6310                 else
6311                 {
6312                         return null;
6313                 }
6314         }
6315
6316         function get_label()
6317         {
6318                 if ($this->label !== null)
6319                 {
6320                         return $this->label;
6321                 }
6322                 else
6323                 {
6324                         return $this->get_term();
6325                 }
6326         }
6327 }
6328
6329 class SimplePie_Enclosure
6330 {
6331         var $bitrate;
6332         var $captions;
6333         var $categories;
6334         var $channels;
6335         var $copyright;
6336         var $credits;
6337         var $description;
6338         var $duration;
6339         var $expression;
6340         var $framerate;
6341         var $handler;
6342         var $hashes;
6343         var $height;
6344         var $javascript;
6345         var $keywords;
6346         var $lang;
6347         var $length;
6348         var $link;
6349         var $medium;
6350         var $player;
6351         var $ratings;
6352         var $restrictions;
6353         var $samplingrate;
6354         var $thumbnails;
6355         var $title;
6356         var $type;
6357         var $width;
6358
6359         // Constructor, used to input the data
6360         function SimplePie_Enclosure($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)
6361         {
6362                 $this->bitrate = $bitrate;
6363                 $this->captions = $captions;
6364                 $this->categories = $categories;
6365                 $this->channels = $channels;
6366                 $this->copyright = $copyright;
6367                 $this->credits = $credits;
6368                 $this->description = $description;
6369                 $this->duration = $duration;
6370                 $this->expression = $expression;
6371                 $this->framerate = $framerate;
6372                 $this->hashes = $hashes;
6373                 $this->height = $height;
6374                 $this->javascript = $javascript;
6375                 $this->keywords = $keywords;
6376                 $this->lang = $lang;
6377                 $this->length = $length;
6378                 $this->link = $link;
6379                 $this->medium = $medium;
6380                 $this->player = $player;
6381                 $this->ratings = $ratings;
6382                 $this->restrictions = $restrictions;
6383                 $this->samplingrate = $samplingrate;
6384                 $this->thumbnails = $thumbnails;
6385                 $this->title = $title;
6386                 $this->type = $type;
6387                 $this->width = $width;
6388                 if (class_exists('idna_convert'))
6389                 {
6390                         $idn =& new idna_convert;
6391                         $parsed = SimplePie_Misc::parse_url($link);
6392                         $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6393                 }
6394                 $this->handler = $this->get_handler(); // Needs to load last
6395         }
6396
6397         function __toString()
6398         {
6399                 // There is no $this->data here
6400                 return md5(serialize($this));
6401         }
6402
6403         function get_bitrate()
6404         {
6405                 if ($this->bitrate !== null)
6406                 {
6407                         return $this->bitrate;
6408                 }
6409                 else
6410                 {
6411                         return null;
6412                 }
6413         }
6414
6415         function get_caption($key = 0)
6416         {
6417                 $captions = $this->get_captions();
6418                 if (isset($captions[$key]))
6419                 {
6420                         return $captions[$key];
6421                 }
6422                 else
6423                 {
6424                         return null;
6425                 }
6426         }
6427
6428         function get_captions()
6429         {
6430                 if ($this->captions !== null)
6431                 {
6432                         return $this->captions;
6433                 }
6434                 else
6435                 {
6436                         return null;
6437                 }
6438         }
6439
6440         function get_category($key = 0)
6441         {
6442                 $categories = $this->get_categories();
6443                 if (isset($categories[$key]))
6444                 {
6445                         return $categories[$key];
6446                 }
6447                 else
6448                 {
6449                         return null;
6450                 }
6451         }
6452
6453         function get_categories()
6454         {
6455                 if ($this->categories !== null)
6456                 {
6457                         return $this->categories;
6458                 }
6459                 else
6460                 {
6461                         return null;
6462                 }
6463         }
6464
6465         function get_channels()
6466         {
6467                 if ($this->channels !== null)
6468                 {
6469                         return $this->channels;
6470                 }
6471                 else
6472                 {
6473                         return null;
6474                 }
6475         }
6476
6477         function get_copyright()
6478         {
6479                 if ($this->copyright !== null)
6480                 {
6481                         return $this->copyright;
6482                 }
6483                 else
6484                 {
6485                         return null;
6486                 }
6487         }
6488
6489         function get_credit($key = 0)
6490         {
6491                 $credits = $this->get_credits();
6492                 if (isset($credits[$key]))
6493                 {
6494                         return $credits[$key];
6495                 }
6496                 else
6497                 {
6498                         return null;
6499                 }
6500         }
6501
6502         function get_credits()
6503         {
6504                 if ($this->credits !== null)
6505                 {
6506                         return $this->credits;
6507                 }
6508                 else
6509                 {
6510                         return null;
6511                 }
6512         }
6513
6514         function get_description()
6515         {
6516                 if ($this->description !== null)
6517                 {
6518                         return $this->description;
6519                 }
6520                 else
6521                 {
6522                         return null;
6523                 }
6524         }
6525
6526         function get_duration($convert = false)
6527         {
6528                 if ($this->duration !== null)
6529                 {
6530                         if ($convert)
6531                         {
6532                                 $time = SimplePie_Misc::time_hms($this->duration);
6533                                 return $time;
6534                         }
6535                         else
6536                         {
6537                                 return $this->duration;
6538                         }
6539                 }
6540                 else
6541                 {
6542                         return null;
6543                 }
6544         }
6545
6546         function get_expression()
6547         {
6548                 if ($this->expression !== null)
6549                 {
6550                         return $this->expression;
6551                 }
6552                 else
6553                 {
6554                         return 'full';
6555                 }
6556         }
6557
6558         function get_extension()
6559         {
6560                 if ($this->link !== null)
6561                 {
6562                         $url = SimplePie_Misc::parse_url($this->link);
6563                         if ($url['path'] !== '')
6564                         {
6565                                 return pathinfo($url['path'], PATHINFO_EXTENSION);
6566                         }
6567                 }
6568                 return null;
6569         }
6570
6571         function get_framerate()
6572         {
6573                 if ($this->framerate !== null)
6574                 {
6575                         return $this->framerate;
6576                 }
6577                 else
6578                 {
6579                         return null;
6580                 }
6581         }
6582
6583         function get_handler()
6584         {
6585                 return $this->get_real_type(true);
6586         }
6587
6588         function get_hash($key = 0)
6589         {
6590                 $hashes = $this->get_hashes();
6591                 if (isset($hashes[$key]))
6592                 {
6593                         return $hashes[$key];
6594                 }
6595                 else
6596                 {
6597                         return null;
6598                 }
6599         }
6600
6601         function get_hashes()
6602         {
6603                 if ($this->hashes !== null)
6604                 {
6605                         return $this->hashes;
6606                 }
6607                 else
6608                 {
6609                         return null;
6610                 }
6611         }
6612
6613         function get_height()
6614         {
6615                 if ($this->height !== null)
6616                 {
6617                         return $this->height;
6618                 }
6619                 else
6620                 {
6621                         return null;
6622                 }
6623         }
6624
6625         function get_language()
6626         {
6627                 if ($this->lang !== null)
6628                 {
6629                         return $this->lang;
6630                 }
6631                 else
6632                 {
6633                         return null;
6634                 }
6635         }
6636
6637         function get_keyword($key = 0)
6638         {
6639                 $keywords = $this->get_keywords();
6640                 if (isset($keywords[$key]))
6641                 {
6642                         return $keywords[$key];
6643                 }
6644                 else
6645                 {
6646                         return null;
6647                 }
6648         }
6649
6650         function get_keywords()
6651         {
6652                 if ($this->keywords !== null)
6653                 {
6654                         return $this->keywords;
6655                 }
6656                 else
6657                 {
6658                         return null;
6659                 }
6660         }
6661
6662         function get_length()
6663         {
6664                 if ($this->length !== null)
6665                 {
6666                         return $this->length;
6667                 }
6668                 else
6669                 {
6670                         return null;
6671                 }
6672         }
6673
6674         function get_link()
6675         {
6676                 if ($this->link !== null)
6677                 {
6678                         return urldecode($this->link);
6679                 }
6680                 else
6681                 {
6682                         return null;
6683                 }
6684         }
6685
6686         function get_medium()
6687         {
6688                 if ($this->medium !== null)
6689                 {
6690                         return $this->medium;
6691                 }
6692                 else
6693                 {
6694                         return null;
6695                 }
6696         }
6697
6698         function get_player()
6699         {
6700                 if ($this->player !== null)
6701                 {
6702                         return $this->player;
6703                 }
6704                 else
6705                 {
6706                         return null;
6707                 }
6708         }
6709
6710         function get_rating($key = 0)
6711         {
6712                 $ratings = $this->get_ratings();
6713                 if (isset($ratings[$key]))
6714                 {
6715                         return $ratings[$key];
6716                 }
6717                 else
6718                 {
6719                         return null;
6720                 }
6721         }
6722
6723         function get_ratings()
6724         {
6725                 if ($this->ratings !== null)
6726                 {
6727                         return $this->ratings;
6728                 }
6729                 else
6730                 {
6731                         return null;
6732                 }
6733         }
6734
6735         function get_restriction($key = 0)
6736         {
6737                 $restrictions = $this->get_restrictions();
6738                 if (isset($restrictions[$key]))
6739                 {
6740                         return $restrictions[$key];
6741                 }
6742                 else
6743                 {
6744                         return null;
6745                 }
6746         }
6747
6748         function get_restrictions()
6749         {
6750                 if ($this->restrictions !== null)
6751                 {
6752                         return $this->restrictions;
6753                 }
6754                 else
6755                 {
6756                         return null;
6757                 }
6758         }
6759
6760         function get_sampling_rate()
6761         {
6762                 if ($this->samplingrate !== null)
6763                 {
6764                         return $this->samplingrate;
6765                 }
6766                 else
6767                 {
6768                         return null;
6769                 }
6770         }
6771
6772         function get_size()
6773         {
6774                 $length = $this->get_length();
6775                 if ($length !== null)
6776                 {
6777                         return round($length/1048576, 2);
6778                 }
6779                 else
6780                 {
6781                         return null;
6782                 }
6783         }
6784
6785         function get_thumbnail($key = 0)
6786         {
6787                 $thumbnails = $this->get_thumbnails();
6788                 if (isset($thumbnails[$key]))
6789                 {
6790                         return $thumbnails[$key];
6791                 }
6792                 else
6793                 {
6794                         return null;
6795                 }
6796         }
6797
6798         function get_thumbnails()
6799         {
6800                 if ($this->thumbnails !== null)
6801                 {
6802                         return $this->thumbnails;
6803                 }
6804                 else
6805                 {
6806                         return null;
6807                 }
6808         }
6809
6810         function get_title()
6811         {
6812                 if ($this->title !== null)
6813                 {
6814                         return $this->title;
6815                 }
6816                 else
6817                 {
6818                         return null;
6819                 }
6820         }
6821
6822         function get_type()
6823         {
6824                 if ($this->type !== null)
6825                 {
6826                         return $this->type;
6827                 }
6828                 else
6829                 {
6830                         return null;
6831                 }
6832         }
6833
6834         function get_width()
6835         {
6836                 if ($this->width !== null)
6837                 {
6838                         return $this->width;
6839                 }
6840                 else
6841                 {
6842                         return null;
6843                 }
6844         }
6845
6846         function native_embed($options='')
6847         {
6848                 return $this->embed($options, true);
6849         }
6850
6851         /**
6852          * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6853          */
6854         function embed($options = '', $native = false)
6855         {
6856                 // Set up defaults
6857                 $audio = '';
6858                 $video = '';
6859                 $alt = '';
6860                 $altclass = '';
6861                 $loop = 'false';
6862                 $width = 'auto';
6863                 $height = 'auto';
6864                 $bgcolor = '#ffffff';
6865                 $mediaplayer = '';
6866                 $widescreen = false;
6867                 $handler = $this->get_handler();
6868                 $type = $this->get_real_type();
6869
6870                 // Process options and reassign values as necessary
6871                 if (is_array($options))
6872                 {
6873                         extract($options);
6874                 }
6875                 else
6876                 {
6877                         $options = explode(',', $options);
6878                         foreach($options as $option)
6879                         {
6880                                 $opt = explode(':', $option, 2);
6881                                 if (isset($opt[0], $opt[1]))
6882                                 {
6883                                         $opt[0] = trim($opt[0]);
6884                                         $opt[1] = trim($opt[1]);
6885                                         switch ($opt[0])
6886                                         {
6887                                                 case 'audio':
6888                                                         $audio = $opt[1];
6889                                                         break;
6890
6891                                                 case 'video':
6892                                                         $video = $opt[1];
6893                                                         break;
6894
6895                                                 case 'alt':
6896                                                         $alt = $opt[1];
6897                                                         break;
6898
6899                                                 case 'altclass':
6900                                                         $altclass = $opt[1];
6901                                                         break;
6902
6903                                                 case 'loop':
6904                                                         $loop = $opt[1];
6905                                                         break;
6906
6907                                                 case 'width':
6908                                                         $width = $opt[1];
6909                                                         break;
6910
6911                                                 case 'height':
6912                                                         $height = $opt[1];
6913                                                         break;
6914
6915                                                 case 'bgcolor':
6916                                                         $bgcolor = $opt[1];
6917                                                         break;
6918
6919                                                 case 'mediaplayer':
6920                                                         $mediaplayer = $opt[1];
6921                                                         break;
6922
6923                                                 case 'widescreen':
6924                                                         $widescreen = $opt[1];
6925                                                         break;
6926                                         }
6927                                 }
6928                         }
6929                 }
6930
6931                 $mime = explode('/', $type, 2);
6932                 $mime = $mime[0];
6933
6934                 // Process values for 'auto'
6935                 if ($width == 'auto')
6936                 {
6937                         if ($mime == 'video')
6938                         {
6939                                 if ($height == 'auto')
6940                                 {
6941                                         $width = 480;
6942                                 }
6943                                 elseif ($widescreen)
6944                                 {
6945                                         $width = round((intval($height)/9)*16);
6946                                 }
6947                                 else
6948                                 {
6949                                         $width = round((intval($height)/3)*4);
6950                                 }
6951                         }
6952                         else
6953                         {
6954                                 $width = '100%';
6955                         }
6956                 }
6957
6958                 if ($height == 'auto')
6959                 {
6960                         if ($mime == 'audio')
6961                         {
6962                                 $height = 0;
6963                         }
6964                         elseif ($mime == 'video')
6965                         {
6966                                 if ($width == 'auto')
6967                                 {
6968                                         if ($widescreen)
6969                                         {
6970                                                 $height = 270;
6971                                         }
6972                                         else
6973                                         {
6974                                                 $height = 360;
6975                                         }
6976                                 }
6977                                 elseif ($widescreen)
6978                                 {
6979                                         $height = round((intval($width)/16)*9);
6980                                 }
6981                                 else
6982                                 {
6983                                         $height = round((intval($width)/4)*3);
6984                                 }
6985                         }
6986                         else
6987                         {
6988                                 $height = 376;
6989                         }
6990                 }
6991                 elseif ($mime == 'audio')
6992                 {
6993                         $height = 0;
6994                 }
6995
6996                 // Set proper placeholder value
6997                 if ($mime == 'audio')
6998                 {
6999                         $placeholder = $audio;
7000                 }
7001                 elseif ($mime == 'video')
7002                 {
7003                         $placeholder = $video;
7004                 }
7005
7006                 $embed = '';
7007
7008                 // Make sure the JS library is included
7009                 if (!$native)
7010                 {
7011                         static $javascript_outputted = null;
7012                         if (!$javascript_outputted && $this->javascript)
7013                         {
7014                                 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7015                                 $javascript_outputted = true;
7016                         }
7017                 }
7018
7019                 // Odeo Feed MP3's
7020                 if ($handler == 'odeo')
7021                 {
7022                         if ($native)
7023                         {
7024                                 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
7025                         }
7026                         else
7027                         {
7028                                 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7029                         }
7030                 }
7031
7032                 // Flash
7033                 elseif ($handler == 'flash')
7034                 {
7035                         if ($native)
7036                         {
7037                                 $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>";
7038                         }
7039                         else
7040                         {
7041                                 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7042                         }
7043                 }
7044
7045                 // Flash Media Player file types.
7046                 // Preferred handler for MP3 file types.
7047                 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7048                 {
7049                         $height += 20;
7050                         if ($native)
7051                         {
7052                                 $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>";
7053                         }
7054                         else
7055                         {
7056                                 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7057                         }
7058                 }
7059
7060                 // QuickTime 7 file types.  Need to test with QuickTime 6.
7061                 // Only handle MP3's if the Flash Media Player is not present.
7062                 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7063                 {
7064                         $height += 16;
7065                         if ($native)
7066                         {
7067                                 if ($placeholder != ""){
7068                                         $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>";
7069                                 }
7070                                 else {
7071                                         $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>";
7072                                 }
7073                         }
7074                         else
7075                         {
7076                                 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7077                         }
7078                 }
7079
7080                 // Windows Media
7081                 elseif ($handler == 'wmedia')
7082                 {
7083                         $height += 45;
7084                         if ($native)
7085                         {
7086                                 $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>";
7087                         }
7088                         else
7089                         {
7090                                 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7091                         }
7092                 }
7093
7094                 // Everything else
7095                 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7096
7097                 return $embed;
7098         }
7099
7100         function get_real_type($find_handler = false)
7101         {
7102                 // If it's Odeo, let's get it out of the way.
7103                 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7104                 {
7105                         return 'odeo';
7106                 }
7107
7108                 // Mime-types by handler.
7109                 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7110                 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7111                 $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
7112                 $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
7113                 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7114
7115                 if ($this->get_type() !== null)
7116                 {
7117                         $type = strtolower($this->type);
7118                 }
7119                 else
7120                 {
7121                         $type = null;
7122                 }
7123
7124                 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7125                 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7126                 {
7127                         switch (strtolower($this->get_extension()))
7128                         {
7129                                 // Audio mime-types
7130                                 case 'aac':
7131                                 case 'adts':
7132                                         $type = 'audio/acc';
7133                                         break;
7134
7135                                 case 'aif':
7136                                 case 'aifc':
7137                                 case 'aiff':
7138                                 case 'cdda':
7139                                         $type = 'audio/aiff';
7140                                         break;
7141
7142                                 case 'bwf':
7143                                         $type = 'audio/wav';
7144                                         break;
7145
7146                                 case 'kar':
7147                                 case 'mid':
7148                                 case 'midi':
7149                                 case 'smf':
7150                                         $type = 'audio/midi';
7151                                         break;
7152
7153                                 case 'm4a':
7154                                         $type = 'audio/x-m4a';
7155                                         break;
7156
7157                                 case 'mp3':
7158                                 case 'swa':
7159                                         $type = 'audio/mp3';
7160                                         break;
7161
7162                                 case 'wav':
7163                                         $type = 'audio/wav';
7164                                         break;
7165
7166                                 case 'wax':
7167                                         $type = 'audio/x-ms-wax';
7168                                         break;
7169
7170                                 case 'wma':
7171                                         $type = 'audio/x-ms-wma';
7172                                         break;
7173
7174                                 // Video mime-types
7175                                 case '3gp':
7176                                 case '3gpp':
7177                                         $type = 'video/3gpp';
7178                                         break;
7179
7180                                 case '3g2':
7181                                 case '3gp2':
7182                                         $type = 'video/3gpp2';
7183                                         break;
7184
7185                                 case 'asf':
7186                                         $type = 'video/x-ms-asf';
7187                                         break;
7188
7189                                 case 'flv':
7190                                         $type = 'video/x-flv';
7191                                         break;
7192
7193                                 case 'm1a':
7194                                 case 'm1s':
7195                                 case 'm1v':
7196                                 case 'm15':
7197                                 case 'm75':
7198                                 case 'mp2':
7199                                 case 'mpa':
7200                                 case 'mpeg':
7201                                 case 'mpg':
7202                                 case 'mpm':
7203                                 case 'mpv':
7204                                         $type = 'video/mpeg';
7205                                         break;
7206
7207                                 case 'm4v':
7208                                         $type = 'video/x-m4v';
7209                                         break;
7210
7211                                 case 'mov':
7212                                 case 'qt':
7213                                         $type = 'video/quicktime';
7214                                         break;
7215
7216                                 case 'mp4':
7217                                 case 'mpg4':
7218                                         $type = 'video/mp4';
7219                                         break;
7220
7221                                 case 'sdv':
7222                                         $type = 'video/sd-video';
7223                                         break;
7224
7225                                 case 'wm':
7226                                         $type = 'video/x-ms-wm';
7227                                         break;
7228
7229                                 case 'wmv':
7230                                         $type = 'video/x-ms-wmv';
7231                                         break;
7232
7233                                 case 'wvx':
7234                                         $type = 'video/x-ms-wvx';
7235                                         break;
7236
7237                                 // Flash mime-types
7238                                 case 'spl':
7239                                         $type = 'application/futuresplash';
7240                                         break;
7241
7242                                 case 'swf':
7243                                         $type = 'application/x-shockwave-flash';
7244                                         break;
7245                         }
7246                 }
7247
7248                 if ($find_handler)
7249                 {
7250                         if (in_array($type, $types_flash))
7251                         {
7252                                 return 'flash';
7253                         }
7254                         elseif (in_array($type, $types_fmedia))
7255                         {
7256                                 return 'fmedia';
7257                         }
7258                         elseif (in_array($type, $types_quicktime))
7259                         {
7260                                 return 'quicktime';
7261                         }
7262                         elseif (in_array($type, $types_wmedia))
7263                         {
7264                                 return 'wmedia';
7265                         }
7266                         elseif (in_array($type, $types_mp3))
7267                         {
7268                                 return 'mp3';
7269                         }
7270                         else
7271                         {
7272                                 return null;
7273                         }
7274                 }
7275                 else
7276                 {
7277                         return $type;
7278                 }
7279         }
7280 }
7281
7282 class SimplePie_Caption
7283 {
7284         var $type;
7285         var $lang;
7286         var $startTime;
7287         var $endTime;
7288         var $text;
7289
7290         // Constructor, used to input the data
7291         function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7292         {
7293                 $this->type = $type;
7294                 $this->lang = $lang;
7295                 $this->startTime = $startTime;
7296                 $this->endTime = $endTime;
7297                 $this->text = $text;
7298         }
7299
7300         function __toString()
7301         {
7302                 // There is no $this->data here
7303                 return md5(serialize($this));
7304         }
7305
7306         function get_endtime()
7307         {
7308                 if ($this->endTime !== null)
7309                 {
7310                         return $this->endTime;
7311                 }
7312                 else
7313                 {
7314                         return null;
7315                 }
7316         }
7317
7318         function get_language()
7319         {
7320                 if ($this->lang !== null)
7321                 {
7322                         return $this->lang;
7323                 }
7324                 else
7325                 {
7326                         return null;
7327                 }
7328         }
7329
7330         function get_starttime()
7331         {
7332                 if ($this->startTime !== null)
7333                 {
7334                         return $this->startTime;
7335                 }
7336                 else
7337                 {
7338                         return null;
7339                 }
7340         }
7341
7342         function get_text()
7343         {
7344                 if ($this->text !== null)
7345                 {
7346                         return $this->text;
7347                 }
7348                 else
7349                 {
7350                         return null;
7351                 }
7352         }
7353
7354         function get_type()
7355         {
7356                 if ($this->type !== null)
7357                 {
7358                         return $this->type;
7359                 }
7360                 else
7361                 {
7362                         return null;
7363                 }
7364         }
7365 }
7366
7367 class SimplePie_Credit
7368 {
7369         var $role;
7370         var $scheme;
7371         var $name;
7372
7373         // Constructor, used to input the data
7374         function SimplePie_Credit($role = null, $scheme = null, $name = null)
7375         {
7376                 $this->role = $role;
7377                 $this->scheme = $scheme;
7378                 $this->name = $name;
7379         }
7380
7381         function __toString()
7382         {
7383                 // There is no $this->data here
7384                 return md5(serialize($this));
7385         }
7386
7387         function get_role()
7388         {
7389                 if ($this->role !== null)
7390                 {
7391                         return $this->role;
7392                 }
7393                 else
7394                 {
7395                         return null;
7396                 }
7397         }
7398
7399         function get_scheme()
7400         {
7401                 if ($this->scheme !== null)
7402                 {
7403                         return $this->scheme;
7404                 }
7405                 else
7406                 {
7407                         return null;
7408                 }
7409         }
7410
7411         function get_name()
7412         {
7413                 if ($this->name !== null)
7414                 {
7415                         return $this->name;
7416                 }
7417                 else
7418                 {
7419                         return null;
7420                 }
7421         }
7422 }
7423
7424 class SimplePie_Copyright
7425 {
7426         var $url;
7427         var $label;
7428
7429         // Constructor, used to input the data
7430         function SimplePie_Copyright($url = null, $label = null)
7431         {
7432                 $this->url = $url;
7433                 $this->label = $label;
7434         }
7435
7436         function __toString()
7437         {
7438                 // There is no $this->data here
7439                 return md5(serialize($this));
7440         }
7441
7442         function get_url()
7443         {
7444                 if ($this->url !== null)
7445                 {
7446                         return $this->url;
7447                 }
7448                 else
7449                 {
7450                         return null;
7451                 }
7452         }
7453
7454         function get_attribution()
7455         {
7456                 if ($this->label !== null)
7457                 {
7458                         return $this->label;
7459                 }
7460                 else
7461                 {
7462                         return null;
7463                 }
7464         }
7465 }
7466
7467 class SimplePie_Rating
7468 {
7469         var $scheme;
7470         var $value;
7471
7472         // Constructor, used to input the data
7473         function SimplePie_Rating($scheme = null, $value = null)
7474         {
7475                 $this->scheme = $scheme;
7476                 $this->value = $value;
7477         }
7478
7479         function __toString()
7480         {
7481                 // There is no $this->data here
7482                 return md5(serialize($this));
7483         }
7484
7485         function get_scheme()
7486         {
7487                 if ($this->scheme !== null)
7488                 {
7489                         return $this->scheme;
7490                 }
7491                 else
7492                 {
7493                         return null;
7494                 }
7495         }
7496
7497         function get_value()
7498         {
7499                 if ($this->value !== null)
7500                 {
7501                         return $this->value;
7502                 }
7503                 else
7504                 {
7505                         return null;
7506                 }
7507         }
7508 }
7509
7510 class SimplePie_Restriction
7511 {
7512         var $relationship;
7513         var $type;
7514         var $value;
7515
7516         // Constructor, used to input the data
7517         function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7518         {
7519                 $this->relationship = $relationship;
7520                 $this->type = $type;
7521                 $this->value = $value;
7522         }
7523
7524         function __toString()
7525         {
7526                 // There is no $this->data here
7527                 return md5(serialize($this));
7528         }
7529
7530         function get_relationship()
7531         {
7532                 if ($this->relationship !== null)
7533                 {
7534                         return $this->relationship;
7535                 }
7536                 else
7537                 {
7538                         return null;
7539                 }
7540         }
7541
7542         function get_type()
7543         {
7544                 if ($this->type !== null)
7545                 {
7546                         return $this->type;
7547                 }
7548                 else
7549                 {
7550                         return null;
7551                 }
7552         }
7553
7554         function get_value()
7555         {
7556                 if ($this->value !== null)
7557                 {
7558                         return $this->value;
7559                 }
7560                 else
7561                 {
7562                         return null;
7563                 }
7564         }
7565 }
7566
7567 /**
7568  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7569  */
7570 class SimplePie_File
7571 {
7572         var $url;
7573         var $useragent;
7574         var $success = true;
7575         var $headers = array();
7576         var $body;
7577         var $status_code;
7578         var $redirects = 0;
7579         var $error;
7580         var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7581
7582         function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7583         {
7584                 if (class_exists('idna_convert'))
7585                 {
7586                         $idn =& new idna_convert;
7587                         $parsed = SimplePie_Misc::parse_url($url);
7588                         $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7589                 }
7590                 $this->url = $url;
7591                 $this->useragent = $useragent;
7592                 if (preg_match('/^http(s)?:\/\//i', $url))
7593                 {
7594                         if ($useragent === null)
7595                         {
7596                                 $useragent = ini_get('user_agent');
7597                                 $this->useragent = $useragent;
7598                         }
7599                         if (!is_array($headers))
7600                         {
7601                                 $headers = array();
7602                         }
7603                         if (!$force_fsockopen && function_exists('curl_exec'))
7604                         {
7605                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7606                                 $fp = curl_init();
7607                                 $headers2 = array();
7608                                 foreach ($headers as $key => $value)
7609                                 {
7610                                         $headers2[] = "$key: $value";
7611                                 }
7612                                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7613                                 {
7614                                         curl_setopt($fp, CURLOPT_ENCODING, '');
7615                                 }
7616                                 curl_setopt($fp, CURLOPT_URL, $url);
7617                                 curl_setopt($fp, CURLOPT_HEADER, 1);
7618                                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7619                                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7620                                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7621                                 curl_setopt($fp, CURLOPT_REFERER, $url);
7622                                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7623                                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7624                                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7625                                 {
7626                                         curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7627                                         curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7628                                 }
7629
7630                                 $this->headers = curl_exec($fp);
7631                                 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7632                                 {
7633                                         curl_setopt($fp, CURLOPT_ENCODING, 'none');
7634                                         $this->headers = curl_exec($fp);
7635                                 }
7636                                 if (curl_errno($fp))
7637                                 {
7638                                         $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7639                                         $this->success = false;
7640                                 }
7641                                 else
7642                                 {
7643                                         $info = curl_getinfo($fp);
7644                                         curl_close($fp);
7645                                         $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7646                                         $this->headers = array_pop($this->headers);
7647                                         $parser =& new SimplePie_HTTP_Parser($this->headers);
7648                                         if ($parser->parse())
7649                                         {
7650                                                 $this->headers = $parser->headers;
7651                                                 $this->body = $parser->body;
7652                                                 $this->status_code = $parser->status_code;
7653                                                 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7654                                                 {
7655                                                         $this->redirects++;
7656                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7657                                                         return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7658                                                 }
7659                                         }
7660                                 }
7661                         }
7662                         else
7663                         {
7664                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7665                                 $url_parts = parse_url($url);
7666                                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7667                                 {
7668                                         $url_parts['host'] = "ssl://$url_parts[host]";
7669                                         $url_parts['port'] = 443;
7670                                 }
7671                                 if (!isset($url_parts['port']))
7672                                 {
7673                                         $url_parts['port'] = 80;
7674                                 }
7675                                 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7676                                 if (!$fp)
7677                                 {
7678                                         $this->error = 'fsockopen error: ' . $errstr;
7679                                         $this->success = false;
7680                                 }
7681                                 else
7682                                 {
7683                                         stream_set_timeout($fp, $timeout);
7684                                         if (isset($url_parts['path']))
7685                                         {
7686                                                 if (isset($url_parts['query']))
7687                                                 {
7688                                                         $get = "$url_parts[path]?$url_parts[query]";
7689                                                 }
7690                                                 else
7691                                                 {
7692                                                         $get = $url_parts['path'];
7693                                                 }
7694                                         }
7695                                         else
7696                                         {
7697                                                 $get = '/';
7698                                         }
7699                                         $out = "GET $get HTTP/1.0\r\n";
7700                                         $out .= "Host: $url_parts[host]\r\n";
7701                                         $out .= "User-Agent: $useragent\r\n";
7702                                         if (extension_loaded('zlib'))
7703                                         {
7704                                                 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7705                                         }
7706
7707                                         if (isset($url_parts['user']) && isset($url_parts['pass']))
7708                                         {
7709                                                 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7710                                         }
7711                                         foreach ($headers as $key => $value)
7712                                         {
7713                                                 $out .= "$key: $value\r\n";
7714                                         }
7715                                         $out .= "Connection: Close\r\n\r\n";
7716                                         fwrite($fp, $out);
7717
7718                                         $info = stream_get_meta_data($fp);
7719
7720                                         $this->headers = '';
7721                                         while (!$info['eof'] && !$info['timed_out'])
7722                                         {
7723                                                 $this->headers .= fread($fp, 1160);
7724                                                 $info = stream_get_meta_data($fp);
7725                                         }
7726                                         if (!$info['timed_out'])
7727                                         {
7728                                                 $parser =& new SimplePie_HTTP_Parser($this->headers);
7729                                                 if ($parser->parse())
7730                                                 {
7731                                                         $this->headers = $parser->headers;
7732                                                         $this->body = $parser->body;
7733                                                         $this->status_code = $parser->status_code;
7734                                                         if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7735                                                         {
7736                                                                 $this->redirects++;
7737                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7738                                                                 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7739                                                         }
7740                                                         if (isset($this->headers['content-encoding']))
7741                                                         {
7742                                                                 // Hey, we act dumb elsewhere, so let's do that here too
7743                                                                 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7744                                                                 {
7745                                                                         case 'gzip':
7746                                                                         case 'x-gzip':
7747                                                                                 $decoder =& new SimplePie_gzdecode($this->body);
7748                                                                                 if (!$decoder->parse())
7749                                                                                 {
7750                                                                                         $this->error = 'Unable to decode HTTP "gzip" stream';
7751                                                                                         $this->success = false;
7752                                                                                 }
7753                                                                                 else
7754                                                                                 {
7755                                                                                         $this->body = $decoder->data;
7756                                                                                 }
7757                                                                                 break;
7758
7759                                                                         case 'deflate':
7760                                                                                 if (($body = gzuncompress($this->body)) === false)
7761                                                                                 {
7762                                                                                         if (($body = gzinflate($this->body)) === false)
7763                                                                                         {
7764                                                                                                 $this->error = 'Unable to decode HTTP "deflate" stream';
7765                                                                                                 $this->success = false;
7766                                                                                         }
7767                                                                                 }
7768                                                                                 $this->body = $body;
7769                                                                                 break;
7770
7771                                                                         default:
7772                                                                                 $this->error = 'Unknown content coding';
7773                                                                                 $this->success = false;
7774                                                                 }
7775                                                         }
7776                                                 }
7777                                         }
7778                                         else
7779                                         {
7780                                                 $this->error = 'fsocket timed out';
7781                                                 $this->success = false;
7782                                         }
7783                                         fclose($fp);
7784                                 }
7785                         }
7786                 }
7787                 else
7788                 {
7789                         $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7790                         if (!$this->body = file_get_contents($url))
7791                         {
7792                                 $this->error = 'file_get_contents could not read the file';
7793                                 $this->success = false;
7794                         }
7795                 }
7796         }
7797 }
7798
7799 /**
7800  * HTTP Response Parser
7801  *
7802  * @package SimplePie
7803  */
7804 class SimplePie_HTTP_Parser
7805 {
7806         /**
7807          * HTTP Version
7808          *
7809          * @access public
7810          * @var float
7811          */
7812         var $http_version = 0.0;
7813
7814         /**
7815          * Status code
7816          *
7817          * @access public
7818          * @var int
7819          */
7820         var $status_code = 0;
7821
7822         /**
7823          * Reason phrase
7824          *
7825          * @access public
7826          * @var string
7827          */
7828         var $reason = '';
7829
7830         /**
7831          * Key/value pairs of the headers
7832          *
7833          * @access public
7834          * @var array
7835          */
7836         var $headers = array();
7837
7838         /**
7839          * Body of the response
7840          *
7841          * @access public
7842          * @var string
7843          */
7844         var $body = '';
7845
7846         /**
7847          * Current state of the state machine
7848          *
7849          * @access private
7850          * @var string
7851          */
7852         var $state = 'http_version';
7853
7854         /**
7855          * Input data
7856          *
7857          * @access private
7858          * @var string
7859          */
7860         var $data = '';
7861
7862         /**
7863          * Input data length (to avoid calling strlen() everytime this is needed)
7864          *
7865          * @access private
7866          * @var int
7867          */
7868         var $data_length = 0;
7869
7870         /**
7871          * Current position of the pointer
7872          *
7873          * @var int
7874          * @access private
7875          */
7876         var $position = 0;
7877
7878         /**
7879          * Name of the hedaer currently being parsed
7880          *
7881          * @access private
7882          * @var string
7883          */
7884         var $name = '';
7885
7886         /**
7887          * Value of the hedaer currently being parsed
7888          *
7889          * @access private
7890          * @var string
7891          */
7892         var $value = '';
7893
7894         /**
7895          * Create an instance of the class with the input data
7896          *
7897          * @access public
7898          * @param string $data Input data
7899          */
7900         function SimplePie_HTTP_Parser($data)
7901         {
7902                 $this->data = $data;
7903                 $this->data_length = strlen($this->data);
7904         }
7905
7906         /**
7907          * Parse the input data
7908          *
7909          * @access public
7910          * @return bool true on success, false on failure
7911          */
7912         function parse()
7913         {
7914                 while ($this->state && $this->state !== 'emit' && $this->has_data())
7915                 {
7916                         $state = $this->state;
7917                         $this->$state();
7918                 }
7919                 $this->data = '';
7920                 if ($this->state === 'emit' || $this->state === 'body')
7921                 {
7922                         return true;
7923                 }
7924                 else
7925                 {
7926                         $this->http_version = '';
7927                         $this->status_code = '';
7928                         $this->reason = '';
7929                         $this->headers = array();
7930                         $this->body = '';
7931                         return false;
7932                 }
7933         }
7934
7935         /**
7936          * Check whether there is data beyond the pointer
7937          *
7938          * @access private
7939          * @return bool true if there is further data, false if not
7940          */
7941         function has_data()
7942         {
7943                 return (bool) ($this->position < $this->data_length);
7944         }
7945
7946         /**
7947          * See if the next character is LWS
7948          *
7949          * @access private
7950          * @return bool true if the next character is LWS, false if not
7951          */
7952         function is_linear_whitespace()
7953         {
7954                 return (bool) ($this->data[$this->position] === "\x09"
7955                         || $this->data[$this->position] === "\x20"
7956                         || ($this->data[$this->position] === "\x0A"
7957                                 && isset($this->data[$this->position + 1])
7958                                 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7959         }
7960
7961         /**
7962          * Parse the HTTP version
7963          *
7964          * @access private
7965          */
7966         function http_version()
7967         {
7968                 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7969                 {
7970                         $len = strspn($this->data, '0123456789.', 5);
7971                         $this->http_version = substr($this->data, 5, $len);
7972                         $this->position += 5 + $len;
7973                         if (substr_count($this->http_version, '.') <= 1)
7974                         {
7975                                 $this->http_version = (float) $this->http_version;
7976                                 $this->position += strspn($this->data, "\x09\x20", $this->position);
7977                                 $this->state = 'status';
7978                         }
7979                         else
7980                         {
7981                                 $this->state = false;
7982                         }
7983                 }
7984                 else
7985                 {
7986                         $this->state = false;
7987                 }
7988         }
7989
7990         /**
7991          * Parse the status code
7992          *
7993          * @access private
7994          */
7995         function status()
7996         {
7997                 if ($len = strspn($this->data, '0123456789', $this->position))
7998                 {
7999                         $this->status_code = (int) substr($this->data, $this->position, $len);
8000                         $this->position += $len;
8001                         $this->state = 'reason';
8002                 }
8003                 else
8004                 {
8005                         $this->state = false;
8006                 }
8007         }
8008
8009         /**
8010          * Parse the reason phrase
8011          *
8012          * @access private
8013          */
8014         function reason()
8015         {
8016                 $len = strcspn($this->data, "\x0A", $this->position);
8017                 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8018                 $this->position += $len + 1;
8019                 $this->state = 'new_line';
8020         }
8021
8022         /**
8023          * Deal with a new line, shifting data around as needed
8024          *
8025          * @access private
8026          */
8027         function new_line()
8028         {
8029                 $this->value = trim($this->value, "\x0D\x20");
8030                 if ($this->name !== '' && $this->value !== '')
8031                 {
8032                         $this->name = strtolower($this->name);
8033                         if (isset($this->headers[$this->name]))
8034                         {
8035                                 $this->headers[$this->name] .= ', ' . $this->value;
8036                         }
8037                         else
8038                         {
8039                                 $this->headers[$this->name] = $this->value;
8040                         }
8041                 }
8042                 $this->name = '';
8043                 $this->value = '';
8044                 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8045                 {
8046                         $this->position += 2;
8047                         $this->state = 'body';
8048                 }
8049                 elseif ($this->data[$this->position] === "\x0A")
8050                 {
8051                         $this->position++;
8052                         $this->state = 'body';
8053                 }
8054                 else
8055                 {
8056                         $this->state = 'name';
8057                 }
8058         }
8059
8060         /**
8061          * Parse a header name
8062          *
8063          * @access private
8064          */
8065         function name()
8066         {
8067                 $len = strcspn($this->data, "\x0A:", $this->position);
8068                 if (isset($this->data[$this->position + $len]))
8069                 {
8070                         if ($this->data[$this->position + $len] === "\x0A")
8071                         {
8072                                 $this->position += $len;
8073                                 $this->state = 'new_line';
8074                         }
8075                         else
8076                         {
8077                                 $this->name = substr($this->data, $this->position, $len);
8078                                 $this->position += $len + 1;
8079                                 $this->state = 'value';
8080                         }
8081                 }
8082                 else
8083                 {
8084                         $this->state = false;
8085                 }
8086         }
8087
8088         /**
8089          * Parse LWS, replacing consecutive LWS characters with a single space
8090          *
8091          * @access private
8092          */
8093         function linear_whitespace()
8094         {
8095                 do
8096                 {
8097                         if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8098                         {
8099                                 $this->position += 2;
8100                         }
8101                         elseif ($this->data[$this->position] === "\x0A")
8102                         {
8103                                 $this->position++;
8104                         }
8105                         $this->position += strspn($this->data, "\x09\x20", $this->position);
8106                 } while ($this->has_data() && $this->is_linear_whitespace());
8107                 $this->value .= "\x20";
8108         }
8109
8110         /**
8111          * See what state to move to while within non-quoted header values
8112          *
8113          * @access private
8114          */
8115         function value()
8116         {
8117                 if ($this->is_linear_whitespace())
8118                 {
8119                         $this->linear_whitespace();
8120                 }
8121                 else
8122                 {
8123                         switch ($this->data[$this->position])
8124                         {
8125                                 case '"':
8126                                         $this->position++;
8127                                         $this->state = 'quote';
8128                                         break;
8129
8130                                 case "\x0A":
8131                                         $this->position++;
8132                                         $this->state = 'new_line';
8133                                         break;
8134
8135                                 default:
8136                                         $this->state = 'value_char';
8137                                         break;
8138                         }
8139                 }
8140         }
8141
8142         /**
8143          * Parse a header value while outside quotes
8144          *
8145          * @access private
8146          */
8147         function value_char()
8148         {
8149                 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8150                 $this->value .= substr($this->data, $this->position, $len);
8151                 $this->position += $len;
8152                 $this->state = 'value';
8153         }
8154
8155         /**
8156          * See what state to move to while within quoted header values
8157          *
8158          * @access private
8159          */
8160         function quote()
8161         {
8162                 if ($this->is_linear_whitespace())
8163                 {
8164                         $this->linear_whitespace();
8165                 }
8166                 else
8167                 {
8168                         switch ($this->data[$this->position])
8169                         {
8170                                 case '"':
8171                                         $this->position++;
8172                                         $this->state = 'value';
8173                                         break;
8174
8175                                 case "\x0A":
8176                                         $this->position++;
8177                                         $this->state = 'new_line';
8178                                         break;
8179
8180                                 case '\\':
8181                                         $this->position++;
8182                                         $this->state = 'quote_escaped';
8183                                         break;
8184
8185                                 default:
8186                                         $this->state = 'quote_char';
8187                                         break;
8188                         }
8189                 }
8190         }
8191
8192         /**
8193          * Parse a header value while within quotes
8194          *
8195          * @access private
8196          */
8197         function quote_char()
8198         {
8199                 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8200                 $this->value .= substr($this->data, $this->position, $len);
8201                 $this->position += $len;
8202                 $this->state = 'value';
8203         }
8204
8205         /**
8206          * Parse an escaped character within quotes
8207          *
8208          * @access private
8209          */
8210         function quote_escaped()
8211         {
8212                 $this->value .= $this->data[$this->position];
8213                 $this->position++;
8214                 $this->state = 'quote';
8215         }
8216
8217         /**
8218          * Parse the body
8219          *
8220          * @access private
8221          */
8222         function body()
8223         {
8224                 $this->body = substr($this->data, $this->position);
8225                 $this->state = 'emit';
8226         }
8227 }
8228
8229 /**
8230  * gzdecode
8231  *
8232  * @package SimplePie
8233  */
8234 class SimplePie_gzdecode
8235 {
8236         /**
8237          * Compressed data
8238          *
8239          * @access private
8240          * @see gzdecode::$data
8241          */
8242         var $compressed_data;
8243
8244         /**
8245          * Size of compressed data
8246          *
8247          * @access private
8248          */
8249         var $compressed_size;
8250
8251         /**
8252          * Minimum size of a valid gzip string
8253          *
8254          * @access private
8255          */
8256         var $min_compressed_size = 18;
8257
8258         /**
8259          * Current position of pointer
8260          *
8261          * @access private
8262          */
8263         var $position = 0;
8264
8265         /**
8266          * Flags (FLG)
8267          *
8268          * @access private
8269          */
8270         var $flags;
8271
8272         /**
8273          * Uncompressed data
8274          *
8275          * @access public
8276          * @see gzdecode::$compressed_data
8277          */
8278         var $data;
8279
8280         /**
8281          * Modified time
8282          *
8283          * @access public
8284          */
8285         var $MTIME;
8286
8287         /**
8288          * Extra Flags
8289          *
8290          * @access public
8291          */
8292         var $XFL;
8293
8294         /**
8295          * Operating System
8296          *
8297          * @access public
8298          */
8299         var $OS;
8300
8301         /**
8302          * Subfield ID 1
8303          *
8304          * @access public
8305          * @see gzdecode::$extra_field
8306          * @see gzdecode::$SI2
8307          */
8308         var $SI1;
8309
8310         /**
8311          * Subfield ID 2
8312          *
8313          * @access public
8314          * @see gzdecode::$extra_field
8315          * @see gzdecode::$SI1
8316          */
8317         var $SI2;
8318
8319         /**
8320          * Extra field content
8321          *
8322          * @access public
8323          * @see gzdecode::$SI1
8324          * @see gzdecode::$SI2
8325          */
8326         var $extra_field;
8327
8328         /**
8329          * Original filename
8330          *
8331          * @access public
8332          */
8333         var $filename;
8334
8335         /**
8336          * Human readable comment
8337          *
8338          * @access public
8339          */
8340         var $comment;
8341
8342         /**
8343          * Don't allow anything to be set
8344          *
8345          * @access public
8346          */
8347         function __set($name, $value)
8348         {
8349                 trigger_error("Cannot write property $name", E_USER_ERROR);
8350         }
8351
8352         /**
8353          * Set the compressed string and related properties
8354          *
8355          * @access public
8356          */
8357         function SimplePie_gzdecode($data)
8358         {
8359                 $this->compressed_data = $data;
8360                 $this->compressed_size = strlen($data);
8361         }
8362
8363         /**
8364          * Decode the GZIP stream
8365          *
8366          * @access public
8367          */
8368         function parse()
8369         {
8370                 if ($this->compressed_size >= $this->min_compressed_size)
8371                 {
8372                         // Check ID1, ID2, and CM
8373                         if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8374                         {
8375                                 return false;
8376                         }
8377
8378                         // Get the FLG (FLaGs)
8379                         $this->flags = ord($this->compressed_data[3]);
8380
8381                         // FLG bits above (1 << 4) are reserved
8382                         if ($this->flags > 0x1F)
8383                         {
8384                                 return false;
8385                         }
8386
8387                         // Advance the pointer after the above
8388                         $this->position += 4;
8389
8390                         // MTIME
8391                         $mtime = substr($this->compressed_data, $this->position, 4);
8392                         // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8393                         if (current(unpack('S', "\x00\x01")) === 1)
8394                         {
8395                                 $mtime = strrev($mtime);
8396                         }
8397                         $this->MTIME = current(unpack('l', $mtime));
8398                         $this->position += 4;
8399
8400                         // Get the XFL (eXtra FLags)
8401                         $this->XFL = ord($this->compressed_data[$this->position++]);
8402
8403                         // Get the OS (Operating System)
8404                         $this->OS = ord($this->compressed_data[$this->position++]);
8405
8406                         // Parse the FEXTRA
8407                         if ($this->flags & 4)
8408                         {
8409                                 // Read subfield IDs
8410                                 $this->SI1 = $this->compressed_data[$this->position++];
8411                                 $this->SI2 = $this->compressed_data[$this->position++];
8412
8413                                 // SI2 set to zero is reserved for future use
8414                                 if ($this->SI2 === "\x00")
8415                                 {
8416                                         return false;
8417                                 }
8418
8419                                 // Get the length of the extra field
8420                                 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8421                                 $position += 2;
8422
8423                                 // Check the length of the string is still valid
8424                                 $this->min_compressed_size += $len + 4;
8425                                 if ($this->compressed_size >= $this->min_compressed_size)
8426                                 {
8427                                         // Set the extra field to the given data
8428                                         $this->extra_field = substr($this->compressed_data, $this->position, $len);
8429                                         $this->position += $len;
8430                                 }
8431                                 else
8432                                 {
8433                                         return false;
8434                                 }
8435                         }
8436
8437                         // Parse the FNAME
8438                         if ($this->flags & 8)
8439                         {
8440                                 // Get the length of the filename
8441                                 $len = strspn($this->compressed_data, "\x00", $this->position);
8442
8443                                 // Check the length of the string is still valid
8444                                 $this->min_compressed_size += $len + 1;
8445                                 if ($this->compressed_size >= $this->min_compressed_size)
8446                                 {
8447                                         // Set the original filename to the given string
8448                                         $this->filename = substr($this->compressed_data, $this->position, $len);
8449                                         $this->position += $len + 1;
8450                                 }
8451                                 else
8452                                 {
8453                                         return false;
8454                                 }
8455                         }
8456
8457                         // Parse the FCOMMENT
8458                         if ($this->flags & 16)
8459                         {
8460                                 // Get the length of the comment
8461                                 $len = strspn($this->compressed_data, "\x00", $this->position);
8462
8463                                 // Check the length of the string is still valid
8464                                 $this->min_compressed_size += $len + 1;
8465                                 if ($this->compressed_size >= $this->min_compressed_size)
8466                                 {
8467                                         // Set the original comment to the given string
8468                                         $this->comment = substr($this->compressed_data, $this->position, $len);
8469                                         $this->position += $len + 1;
8470                                 }
8471                                 else
8472                                 {
8473                                         return false;
8474                                 }
8475                         }
8476
8477                         // Parse the FHCRC
8478                         if ($this->flags & 2)
8479                         {
8480                                 // Check the length of the string is still valid
8481                                 $this->min_compressed_size += $len + 2;
8482                                 if ($this->compressed_size >= $this->min_compressed_size)
8483                                 {
8484                                         // Read the CRC
8485                                         $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8486
8487                                         // Check the CRC matches
8488                                         if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8489                                         {
8490                                                 $this->position += 2;
8491                                         }
8492                                         else
8493                                         {
8494                                                 return false;
8495                                         }
8496                                 }
8497                                 else
8498                                 {
8499                                         return false;
8500                                 }
8501                         }
8502
8503                         // Decompress the actual data
8504                         if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8505                         {
8506                                 return false;
8507                         }
8508                         else
8509                         {
8510                                 $this->position = $this->compressed_size - 8;
8511                         }
8512
8513                         // Check CRC of data
8514                         $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8515                         $this->position += 4;
8516                         /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8517                         {
8518                                 return false;
8519                         }*/
8520
8521                         // Check ISIZE of data
8522                         $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8523                         $this->position += 4;
8524                         if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8525                         {
8526                                 return false;
8527                         }
8528
8529                         // Wow, against all odds, we've actually got a valid gzip string
8530                         return true;
8531                 }
8532                 else
8533                 {
8534                         return false;
8535                 }
8536         }
8537 }
8538
8539 class SimplePie_Cache
8540 {
8541         /**
8542          * Don't call the constructor. Please.
8543          *
8544          * @access private
8545          */
8546         function SimplePie_Cache()
8547         {
8548                 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8549         }
8550
8551         /**
8552          * Create a new SimplePie_Cache object
8553          *
8554          * @static
8555          * @access public
8556          */
8557         function create($location, $filename, $extension)
8558         {
8559                 return new SimplePie_Cache_File($location, $filename, $extension);
8560         }
8561 }
8562
8563 class SimplePie_Cache_File
8564 {
8565         var $location;
8566         var $filename;
8567         var $extension;
8568         var $name;
8569
8570         function SimplePie_Cache_File($location, $filename, $extension)
8571         {
8572                 $this->location = $location;
8573                 $this->filename = rawurlencode($filename);
8574                 $this->extension = rawurlencode($extension);
8575                 $this->name = "$location/$this->filename.$this->extension";
8576         }
8577
8578         function save($data)
8579         {
8580                 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8581                 {
8582                         if (is_a($data, 'SimplePie'))
8583                         {
8584                                 $data = $data->data;
8585                         }
8586
8587                         $data = serialize($data);
8588
8589                         if (function_exists('file_put_contents'))
8590                         {
8591                                 return (bool) file_put_contents($this->name, $data);
8592                         }
8593                         else
8594                         {
8595                                 $fp = fopen($this->name, 'wb');
8596                                 if ($fp)
8597                                 {
8598                                         fwrite($fp, $data);
8599                                         fclose($fp);
8600                                         return true;
8601                                 }
8602                         }
8603                 }
8604                 return false;
8605         }
8606
8607         function load()
8608         {
8609                 if (file_exists($this->name) && is_readable($this->name))
8610                 {
8611                         return unserialize(file_get_contents($this->name));
8612                 }
8613                 return false;
8614         }
8615
8616         function mtime()
8617         {
8618                 if (file_exists($this->name))
8619                 {
8620                         return filemtime($this->name);
8621                 }
8622                 return false;
8623         }
8624
8625         function touch()
8626         {
8627                 if (file_exists($this->name))
8628                 {
8629                         return touch($this->name);
8630                 }
8631                 return false;
8632         }
8633
8634         function unlink()
8635         {
8636                 if (file_exists($this->name))
8637                 {
8638                         return unlink($this->name);
8639                 }
8640                 return false;
8641         }
8642 }
8643
8644 class SimplePie_Misc
8645 {
8646         function time_hms($seconds)
8647         {
8648                 $time = '';
8649
8650                 $hours = floor($seconds / 3600);
8651                 $remainder = $seconds % 3600;
8652                 if ($hours > 0)
8653                 {
8654                         $time .= $hours.':';
8655                 }
8656
8657                 $minutes = floor($remainder / 60);
8658                 $seconds = $remainder % 60;
8659                 if ($minutes < 10 && $hours > 0)
8660                 {
8661                         $minutes = '0' . $minutes;
8662                 }
8663                 if ($seconds < 10)
8664                 {
8665                         $seconds = '0' . $seconds;
8666                 }
8667
8668                 $time .= $minutes.':';
8669                 $time .= $seconds;
8670
8671                 return $time;
8672         }
8673
8674         function absolutize_url($relative, $base)
8675         {
8676                 if ($relative !== '')
8677                 {
8678                         $relative = SimplePie_Misc::parse_url($relative);
8679                         if ($relative['scheme'] !== '')
8680                         {
8681                                 $target = $relative;
8682                         }
8683                         elseif ($base !== '')
8684                         {
8685                                 $base = SimplePie_Misc::parse_url($base);
8686                                 $target = SimplePie_Misc::parse_url('');
8687                                 if ($relative['authority'] !== '')
8688                                 {
8689                                         $target = $relative;
8690                                         $target['scheme'] = $base['scheme'];
8691                                 }
8692                                 else
8693                                 {
8694                                         $target['scheme'] = $base['scheme'];
8695                                         $target['authority'] = $base['authority'];
8696                                         if ($relative['path'] !== '')
8697                                         {
8698                                                 if (strpos($relative['path'], '/') === 0)
8699                                                 {
8700                                                         $target['path'] = $relative['path'];
8701                                                 }
8702                                                 elseif ($base['authority'] !== '' && $base['path'] === '')
8703                                                 {
8704                                                         $target['path'] = '/' . $relative['path'];
8705                                                 }
8706                                                 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8707                                                 {
8708                                                         $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8709                                                 }
8710                                                 else
8711                                                 {
8712                                                         $target['path'] = $relative['path'];
8713                                                 }
8714                                                 $target['query'] = $relative['query'];
8715                                         }
8716                                         else
8717                                         {
8718                                                 $target['path'] = $base['path'];
8719                                                 if ($relative['query'] !== '')
8720                                                 {
8721                                                         $target['query'] = $relative['query'];
8722                                                 }
8723                                                 elseif ($base['query'] !== '')
8724                                                 {
8725                                                         $target['query'] = $base['query'];
8726                                                 }
8727                                         }
8728                                 }
8729                                 $target['fragment'] = $relative['fragment'];
8730                         }
8731                         else
8732                         {
8733                                 // No base URL, just return the relative URL
8734                                 $target = $relative;
8735                         }
8736                         $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8737                 }
8738                 else
8739                 {
8740                         $return = $base;
8741                 }
8742                 $return = SimplePie_Misc::normalize_url($return);
8743                 return $return;
8744         }
8745
8746         function remove_dot_segments($input)
8747         {
8748                 $output = '';
8749                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8750                 {
8751                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8752                         if (strpos($input, '../') === 0)
8753                         {
8754                                 $input = substr($input, 3);
8755                         }
8756                         elseif (strpos($input, './') === 0)
8757                         {
8758                                 $input = substr($input, 2);
8759                         }
8760                         // 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,
8761                         elseif (strpos($input, '/./') === 0)
8762                         {
8763                                 $input = substr_replace($input, '/', 0, 3);
8764                         }
8765                         elseif ($input == '/.')
8766                         {
8767                                 $input = '/';
8768                         }
8769                         // 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,
8770                         elseif (strpos($input, '/../') === 0)
8771                         {
8772                                 $input = substr_replace($input, '/', 0, 4);
8773                                 $output = substr_replace($output, '', strrpos($output, '/'));
8774                         }
8775                         elseif ($input == '/..')
8776                         {
8777                                 $input = '/';
8778                                 $output = substr_replace($output, '', strrpos($output, '/'));
8779                         }
8780                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8781                         elseif ($input == '.' || $input == '..')
8782                         {
8783                                 $input = '';
8784                         }
8785                         // 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
8786                         elseif (($pos = strpos($input, '/', 1)) !== false)
8787                         {
8788                                 $output .= substr($input, 0, $pos);
8789                                 $input = substr_replace($input, '', 0, $pos);
8790                         }
8791                         else
8792                         {
8793                                 $output .= $input;
8794                                 $input = '';
8795                         }
8796                 }
8797                 return $output . $input;
8798         }
8799
8800         function get_element($realname, $string)
8801         {
8802                 $return = array();
8803                 $name = preg_quote($realname, '/');
8804                 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8805                 {
8806                         for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8807                         {
8808                                 $return[$i]['tag'] = $realname;
8809                                 $return[$i]['full'] = $matches[$i][0][0];
8810                                 $return[$i]['offset'] = $matches[$i][0][1];
8811                                 if (strlen($matches[$i][3][0]) <= 2)
8812                                 {
8813                                         $return[$i]['self_closing'] = true;
8814                                 }
8815                                 else
8816                                 {
8817                                         $return[$i]['self_closing'] = false;
8818                                         $return[$i]['content'] = $matches[$i][4][0];
8819                                 }
8820                                 $return[$i]['attribs'] = array();
8821                                 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))
8822                                 {
8823                                         for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8824                                         {
8825                                                 if (count($attribs[$j]) == 2)
8826                                                 {
8827                                                         $attribs[$j][2] = $attribs[$j][1];
8828                                                 }
8829                                                 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8830                                         }
8831                                 }
8832                         }
8833                 }
8834                 return $return;
8835         }
8836
8837         function element_implode($element)
8838         {
8839                 $full = "<$element[tag]";
8840                 foreach ($element['attribs'] as $key => $value)
8841                 {
8842                         $key = strtolower($key);
8843                         $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8844                 }
8845                 if ($element['self_closing'])
8846                 {
8847                         $full .= ' />';
8848                 }
8849                 else
8850                 {
8851                         $full .= ">$element[content]</$element[tag]>";
8852                 }
8853                 return $full;
8854         }
8855
8856         function error($message, $level, $file, $line)
8857         {
8858                 switch ($level)
8859                 {
8860                         case E_USER_ERROR:
8861                                 $note = 'PHP Error';
8862                                 break;
8863                         case E_USER_WARNING:
8864                                 $note = 'PHP Warning';
8865                                 break;
8866                         case E_USER_NOTICE:
8867                                 $note = 'PHP Notice';
8868                                 break;
8869                         default:
8870                                 $note = 'Unknown Error';
8871                                 break;
8872                 }
8873                 error_log("$note: $message in $file on line $line", 0);
8874                 return $message;
8875         }
8876
8877         /**
8878          * If a file has been cached, retrieve and display it.
8879          *
8880          * This is most useful for caching images (get_favicon(), etc.),
8881          * however it works for all cached files.  This WILL NOT display ANY
8882          * file/image/page/whatever, but rather only display what has already
8883          * been cached by SimplePie.
8884          *
8885          * @access public
8886          * @see SimplePie::get_favicon()
8887          * @param str $identifier_url URL that is used to identify the content.
8888          * This may or may not be the actual URL of the live content.
8889          * @param str $cache_location Location of SimplePie's cache.  Defaults
8890          * to './cache'.
8891          * @param str $cache_extension The file extension that the file was
8892          * cached with.  Defaults to 'spc'.
8893          * @param str $cache_class Name of the cache-handling class being used
8894          * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
8895          * as-is unless you've overloaded the class.
8896          * @param str $cache_name_function Obsolete. Exists for backwards
8897          * compatibility reasons only.
8898          */
8899         function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8900         {
8901                 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8902
8903                 if ($file = $cache->load())
8904                 {
8905                         if (isset($file['headers']['content-type']))
8906                         {
8907                                 header('Content-type:' . $file['headers']['content-type']);
8908                         }
8909                         else
8910                         {
8911                                 header('Content-type: application/octet-stream');
8912                         }
8913                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8914                         echo $file['body'];
8915                         exit;
8916                 }
8917
8918                 die('Cached file for ' . $identifier_url . ' cannot be found.');
8919         }
8920
8921         function fix_protocol($url, $http = 1)
8922         {
8923                 $url = SimplePie_Misc::normalize_url($url);
8924                 $parsed = SimplePie_Misc::parse_url($url);
8925                 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8926                 {
8927                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8928                 }
8929
8930                 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8931                 {
8932                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8933                 }
8934
8935                 if ($http == 2 && $parsed['scheme'] !== '')
8936                 {
8937                         return "feed:$url";
8938                 }
8939                 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8940                 {
8941                         return substr_replace($url, 'podcast', 0, 4);
8942                 }
8943                 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8944                 {
8945                         return substr_replace($url, 'itpc', 0, 4);
8946                 }
8947                 else
8948                 {
8949                         return $url;
8950                 }
8951         }
8952
8953         function parse_url($url)
8954         {
8955                 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match);
8956                 for ($i = count($match); $i <= 9; $i++)
8957                 {
8958                         $match[$i] = '';
8959                 }
8960                 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8961         }
8962
8963         function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8964         {
8965                 $return = '';
8966                 if ($scheme !== '')
8967                 {
8968                         $return .= "$scheme:";
8969                 }
8970                 if ($authority !== '')
8971                 {
8972                         $return .= "//$authority";
8973                 }
8974                 if ($path !== '')
8975                 {
8976                         $return .= $path;
8977                 }
8978                 if ($query !== '')
8979                 {
8980                         $return .= "?$query";
8981                 }
8982                 if ($fragment !== '')
8983                 {
8984                         $return .= "#$fragment";
8985                 }
8986                 return $return;
8987         }
8988
8989         function normalize_url($url)
8990         {
8991                 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8992                 $url = SimplePie_Misc::parse_url($url);
8993                 $url['scheme'] = strtolower($url['scheme']);
8994                 if ($url['authority'] !== '')
8995                 {
8996                         $url['authority'] = strtolower($url['authority']);
8997                         $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8998                 }
8999                 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9000         }
9001
9002         function percent_encoding_normalization($match)
9003         {
9004                 $integer = hexdec($match[1]);
9005                 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9006                 {
9007                         return chr($integer);
9008                 }
9009                 else
9010                 {
9011                         return strtoupper($match[0]);
9012                 }
9013         }
9014
9015         /**
9016          * Remove bad UTF-8 bytes
9017          *
9018          * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9019          * FAQ: Multilingual Forms (modified to include full ASCII range)
9020          *
9021          * @author Geoffrey Sneddon
9022          * @see http://www.w3.org/International/questions/qa-forms-utf-8
9023          * @param string $str String to remove bad UTF-8 bytes from
9024          * @return string UTF-8 string
9025          */
9026         function utf8_bad_replace($str)
9027         {
9028                 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9029                 {
9030                         return $return;
9031                 }
9032                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9033                 {
9034                         return $return;
9035                 }
9036                 elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
9037                 {
9038                         return implode("\xEF\xBF\xBD", $matches[0]);
9039                 }
9040                 elseif ($str !== '')
9041                 {
9042                         return "\xEF\xBF\xBD";
9043                 }
9044                 else
9045                 {
9046                         return '';
9047                 }
9048         }
9049
9050         /**
9051          * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9052          *
9053          * @static
9054          * @access public
9055          * @param string $string Windows-1252 encoded string
9056          * @return string UTF-8 encoded string
9057          */
9058         function windows_1252_to_utf8($string)
9059         {
9060                 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");
9061
9062                 return strtr($string, $convert_table);
9063         }
9064
9065         function change_encoding($data, $input, $output)
9066         {
9067                 $input = SimplePie_Misc::encoding($input);
9068                 $output = SimplePie_Misc::encoding($output);
9069
9070                 // We fail to fail on non US-ASCII bytes
9071                 if ($input === 'US-ASCII')
9072                 {
9073                         static $non_ascii_octects = '';
9074                         if (!$non_ascii_octects)
9075                         {
9076                                 for ($i = 0x80; $i <= 0xFF; $i++)
9077                                 {
9078                                         $non_ascii_octects .= chr($i);
9079                                 }
9080                         }
9081                         $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9082                 }
9083
9084                 // This is first, as behaviour of this is completely predictable
9085                 if ($input === 'Windows-1252' && $output === 'UTF-8')
9086                 {
9087                         return SimplePie_Misc::windows_1252_to_utf8($data);
9088                 }
9089                 // This is second, as behaviour of this varies only with PHP version
9090                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9091                 {
9092                         return $return;
9093                 }
9094                 // This is last, as behaviour of this varies with OS userland and PHP version
9095                 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9096                 {
9097                         return $return;
9098                 }
9099                 // If we can't do anything, just fail
9100                 else
9101                 {
9102                         return false;
9103                 }
9104         }
9105
9106         function encoding($charset)
9107         {
9108                 /* Character sets are case-insensitive, and also need some further
9109                 normalization in the real world (though we'll return them in the form given
9110                 in their registration). */
9111                 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9112                 {
9113                         case 'adobestandardencoding':
9114                         case 'csadobestandardencoding':
9115                                 return 'Adobe-Standard-Encoding';
9116
9117                         case 'adobesymbolencoding':
9118                         case 'cshppsmath':
9119                                 return 'Adobe-Symbol-Encoding';
9120
9121                         case 'ami1251':
9122                         case 'ami1251':
9123                         case 'amiga1251':
9124                         case 'amiga1251':
9125                                 return 'Amiga-1251';
9126
9127                         case 'ansix31101983':
9128                         case 'csat5001983':
9129                         case 'csiso99naplps':
9130                         case 'isoir99':
9131                         case 'naplps':
9132                                 return 'ANSI_X3.110-1983';
9133
9134                         case 'arabic7':
9135                         case 'asmo449':
9136                         case 'csiso89asmo449':
9137                         case 'isoir89':
9138                         case 'iso9036':
9139                                 return 'ASMO_449';
9140
9141                         case 'big5':
9142                         case 'csbig5':
9143                         case 'xxbig5':
9144                                 return 'Big5';
9145
9146                         case 'big5hkscs':
9147                                 return 'Big5-HKSCS';
9148
9149                         case 'bocu1':
9150                         case 'csbocu1':
9151                                 return 'BOCU-1';
9152
9153                         case 'brf':
9154                         case 'csbrf':
9155                                 return 'BRF';
9156
9157                         case 'bs4730':
9158                         case 'csiso4unitedkingdom':
9159                         case 'gb':
9160                         case 'isoir4':
9161                         case 'iso646gb':
9162                         case 'uk':
9163                                 return 'BS_4730';
9164
9165                         case 'bsviewdata':
9166                         case 'csiso47bsviewdata':
9167                         case 'isoir47':
9168                                 return 'BS_viewdata';
9169
9170                         case 'cesu8':
9171                         case 'cscesu8':
9172                                 return 'CESU-8';
9173
9174                         case 'ca':
9175                         case 'csa71':
9176                         case 'csaz243419851':
9177                         case 'csiso121canadian1':
9178                         case 'isoir121':
9179                         case 'iso646ca':
9180                                 return 'CSA_Z243.4-1985-1';
9181
9182                         case 'csa72':
9183                         case 'csaz243419852':
9184                         case 'csiso122canadian2':
9185                         case 'isoir122':
9186                         case 'iso646ca2':
9187                                 return 'CSA_Z243.4-1985-2';
9188
9189                         case 'csaz24341985gr':
9190                         case 'csiso123csaz24341985gr':
9191                         case 'isoir123':
9192                                 return 'CSA_Z243.4-1985-gr';
9193
9194                         case 'csiso139csn369103':
9195                         case 'csn369103':
9196                         case 'isoir139':
9197                                 return 'CSN_369103';
9198
9199                         case 'csdecmcs':
9200                         case 'dec':
9201                         case 'decmcs':
9202                                 return 'DEC-MCS';
9203
9204                         case 'csiso21german':
9205                         case 'de':
9206                         case 'din66003':
9207                         case 'isoir21':
9208                         case 'iso646de':
9209                                 return 'DIN_66003';
9210
9211                         case 'csdkus':
9212                         case 'dkus':
9213                                 return 'dk-us';
9214
9215                         case 'csiso646danish':
9216                         case 'dk':
9217                         case 'ds2089':
9218                         case 'ds2089':
9219                         case 'iso646dk':
9220                                 return 'DS_2089';
9221
9222                         case 'csibmebcdicatde':
9223                         case 'ebcdicatde':
9224                                 return 'EBCDIC-AT-DE';
9225
9226                         case 'csebcdicatdea':
9227                         case 'ebcdicatdea':
9228                                 return 'EBCDIC-AT-DE-A';
9229
9230                         case 'csebcdiccafr':
9231                         case 'ebcdiccafr':
9232                                 return 'EBCDIC-CA-FR';
9233
9234                         case 'csebcdicdkno':
9235                         case 'ebcdicdkno':
9236                                 return 'EBCDIC-DK-NO';
9237
9238                         case 'csebcdicdknoa':
9239                         case 'ebcdicdknoa':
9240                                 return 'EBCDIC-DK-NO-A';
9241
9242                         case 'csebcdices':
9243                         case 'ebcdices':
9244                                 return 'EBCDIC-ES';
9245
9246                         case 'csebcdicesa':
9247                         case 'ebcdicesa':
9248                                 return 'EBCDIC-ES-A';
9249
9250                         case 'csebcdicess':
9251                         case 'ebcdicess':
9252                                 return 'EBCDIC-ES-S';
9253
9254                         case 'csebcdicfise':
9255                         case 'ebcdicfise':
9256                                 return 'EBCDIC-FI-SE';
9257
9258                         case 'csebcdicfisea':
9259                         case 'ebcdicfisea':
9260                                 return 'EBCDIC-FI-SE-A';
9261
9262                         case 'csebcdicfr':
9263                         case 'ebcdicfr':
9264                                 return 'EBCDIC-FR';
9265
9266                         case 'csebcdicit':
9267                         case 'ebcdicit':
9268                                 return 'EBCDIC-IT';
9269
9270                         case 'csebcdicpt':
9271                         case 'ebcdicpt':
9272                                 return 'EBCDIC-PT';
9273
9274                         case 'csebcdicuk':
9275                         case 'ebcdicuk':
9276                                 return 'EBCDIC-UK';
9277
9278                         case 'csebcdicus':
9279                         case 'ebcdicus':
9280                                 return 'EBCDIC-US';
9281
9282                         case 'csiso111ecmacyrillic':
9283                         case 'ecmacyrillic':
9284                         case 'isoir111':
9285                         case 'koi8e':
9286                                 return 'ECMA-cyrillic';
9287
9288                         case 'csiso17spanish':
9289                         case 'es':
9290                         case 'isoir17':
9291                         case 'iso646es':
9292                                 return 'ES';
9293
9294                         case 'csiso85spanish2':
9295                         case 'es2':
9296                         case 'isoir85':
9297                         case 'iso646es2':
9298                                 return 'ES2';
9299
9300                         case 'cseucfixwidjapanese':
9301                         case 'extendedunixcodefixedwidthforjapanese':
9302                                 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9303
9304                         case 'cseucpkdfmtjapanese':
9305                         case 'eucjp':
9306                         case 'extendedunixcodepackedformatforjapanese':
9307                                 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9308
9309                         case 'gb18030':
9310                                 return 'GB18030';
9311
9312                         case 'cp936':
9313                         case 'gbk':
9314                         case 'ms936':
9315                         case 'windows936':
9316                         case 'csgb2312':
9317                         case 'gb2312':
9318                         case 'chinese':
9319                         case 'csiso58gb231280':
9320                         case 'gb231280':
9321                         case 'isoir58':
9322                                 return 'GBK';
9323
9324                         case 'cn':
9325                         case 'csiso57gb1988':
9326                         case 'gb198880':
9327                         case 'isoir57':
9328                         case 'iso646cn':
9329                                 return 'GB_1988-80';
9330
9331                         case 'csiso153gost1976874':
9332                         case 'gost1976874':
9333                         case 'isoir153':
9334                         case 'stsev35888':
9335                                 return 'GOST_19768-74';
9336
9337                         case 'csiso150':
9338                         case 'csiso150greekccitt':
9339                         case 'greekccitt':
9340                         case 'isoir150':
9341                                 return 'greek-ccitt';
9342
9343                         case 'csiso88greek7':
9344                         case 'greek7':
9345                         case 'isoir88':
9346                                 return 'greek7';
9347
9348                         case 'csiso18greek7old':
9349                         case 'greek7old':
9350                         case 'isoir18':
9351                                 return 'greek7-old';
9352
9353                         case 'cshpdesktop':
9354                         case 'hpdesktop':
9355                                 return 'HP-DeskTop';
9356
9357                         case 'cshplegal':
9358                         case 'hplegal':
9359                                 return 'HP-Legal';
9360
9361                         case 'cshpmath8':
9362                         case 'hpmath8':
9363                                 return 'HP-Math8';
9364
9365                         case 'cshppifont':
9366                         case 'hppifont':
9367                                 return 'HP-Pi-font';
9368
9369                         case 'cshproman8':
9370                         case 'hproman8':
9371                         case 'r8':
9372                         case 'roman8':
9373                                 return 'hp-roman8';
9374
9375                         case 'hzgb2312':
9376                                 return 'HZ-GB-2312';
9377
9378                         case 'csibmsymbols':
9379                         case 'ibmsymbols':
9380                                 return 'IBM-Symbols';
9381
9382                         case 'csibmthai':
9383                         case 'ibmthai':
9384                                 return 'IBM-Thai';
9385
9386                         case 'ccsid00858':
9387                         case 'cp00858':
9388                         case 'ibm00858':
9389                         case 'pcmultilingual850euro':
9390                                 return 'IBM00858';
9391
9392                         case 'ccsid00924':
9393                         case 'cp00924':
9394                         case 'ebcdiclatin9euro':
9395                         case 'ibm00924':
9396                                 return 'IBM00924';
9397
9398                         case 'ccsid01140':
9399                         case 'cp01140':
9400                         case 'ebcdicus37euro':
9401                         case 'ibm01140':
9402                                 return 'IBM01140';
9403
9404                         case 'ccsid01141':
9405                         case 'cp01141':
9406                         case 'ebcdicde273euro':
9407                         case 'ibm01141':
9408                                 return 'IBM01141';
9409
9410                         case 'ccsid01142':
9411                         case 'cp01142':
9412                         case 'ebcdicdk277euro':
9413                         case 'ebcdicno277euro':
9414                         case 'ibm01142':
9415                                 return 'IBM01142';
9416
9417                         case 'ccsid01143':
9418                         case 'cp01143':
9419                         case 'ebcdicfi278euro':
9420                         case 'ebcdicse278euro':
9421                         case 'ibm01143':
9422                                 return 'IBM01143';
9423
9424                         case 'ccsid01144':
9425                         case 'cp01144':
9426                         case 'ebcdicit280euro':
9427                         case 'ibm01144':
9428                                 return 'IBM01144';
9429
9430                         case 'ccsid01145':
9431                         case 'cp01145':
9432                         case 'ebcdices284euro':
9433                         case 'ibm01145':
9434                                 return 'IBM01145';
9435
9436                         case 'ccsid01146':
9437                         case 'cp01146':
9438                         case 'ebcdicgb285euro':
9439                         case 'ibm01146':
9440                                 return 'IBM01146';
9441
9442                         case 'ccsid01147':
9443                         case 'cp01147':
9444                         case 'ebcdicfr297euro':
9445                         case 'ibm01147':
9446                                 return 'IBM01147';
9447
9448                         case 'ccsid01148':
9449                         case 'cp01148':
9450                         case 'ebcdicinternational500euro':
9451                         case 'ibm01148':
9452                                 return 'IBM01148';
9453
9454                         case 'ccsid01149':
9455                         case 'cp01149':
9456                         case 'ebcdicis871euro':
9457                         case 'ibm01149':
9458                                 return 'IBM01149';
9459
9460                         case 'cp037':
9461                         case 'csibm037':
9462                         case 'ebcdiccpca':
9463                         case 'ebcdiccpnl':
9464                         case 'ebcdiccpus':
9465                         case 'ebcdiccpwt':
9466                         case 'ibm037':
9467                                 return 'IBM037';
9468
9469                         case 'cp038':
9470                         case 'csibm038':
9471                         case 'ebcdicint':
9472                         case 'ibm038':
9473                                 return 'IBM038';
9474
9475                         case 'cp273':
9476                         case 'csibm273':
9477                         case 'ibm273':
9478                                 return 'IBM273';
9479
9480                         case 'cp274':
9481                         case 'csibm274':
9482                         case 'ebcdicbe':
9483                         case 'ibm274':
9484                                 return 'IBM274';
9485
9486                         case 'cp275':
9487                         case 'csibm275':
9488                         case 'ebcdicbr':
9489                         case 'ibm275':
9490                                 return 'IBM275';
9491
9492                         case 'csibm277':
9493                         case 'ebcdiccpdk':
9494                         case 'ebcdiccpno':
9495                         case 'ibm277':
9496                                 return 'IBM277';
9497
9498                         case 'cp278':
9499                         case 'csibm278':
9500                         case 'ebcdiccpfi':
9501                         case 'ebcdiccpse':
9502                         case 'ibm278':
9503                                 return 'IBM278';
9504
9505                         case 'cp280':
9506                         case 'csibm280':
9507                         case 'ebcdiccpit':
9508                         case 'ibm280':
9509                                 return 'IBM280';
9510
9511                         case 'cp281':
9512                         case 'csibm281':
9513                         case 'ebcdicjpe':
9514                         case 'ibm281':
9515                                 return 'IBM281';
9516
9517                         case 'cp284':
9518                         case 'csibm284':
9519                         case 'ebcdiccpes':
9520                         case 'ibm284':
9521                                 return 'IBM284';
9522
9523                         case 'cp285':
9524                         case 'csibm285':
9525                         case 'ebcdiccpgb':
9526                         case 'ibm285':
9527                                 return 'IBM285';
9528
9529                         case 'cp290':
9530                         case 'csibm290':
9531                         case 'ebcdicjpkana':
9532                         case 'ibm290':
9533                                 return 'IBM290';
9534
9535                         case 'cp297':
9536                         case 'csibm297':
9537                         case 'ebcdiccpfr':
9538                         case 'ibm297':
9539                                 return 'IBM297';
9540
9541                         case 'cp420':
9542                         case 'csibm420':
9543                         case 'ebcdiccpar1':
9544                         case 'ibm420':
9545                                 return 'IBM420';
9546
9547                         case 'cp423':
9548                         case 'csibm423':
9549                         case 'ebcdiccpgr':
9550                         case 'ibm423':
9551                                 return 'IBM423';
9552
9553                         case 'cp424':
9554                         case 'csibm424':
9555                         case 'ebcdiccphe':
9556                         case 'ibm424':
9557                                 return 'IBM424';
9558
9559                         case '437':
9560                         case 'cp437':
9561                         case 'cspc8codepage437':
9562                         case 'ibm437':
9563                                 return 'IBM437';
9564
9565                         case 'cp500':
9566                         case 'csibm500':
9567                         case 'ebcdiccpbe':
9568                         case 'ebcdiccpch':
9569                         case 'ibm500':
9570                                 return 'IBM500';
9571
9572                         case 'cp775':
9573                         case 'cspc775baltic':
9574                         case 'ibm775':
9575                                 return 'IBM775';
9576
9577                         case '850':
9578                         case 'cp850':
9579                         case 'cspc850multilingual':
9580                         case 'ibm850':
9581                                 return 'IBM850';
9582
9583                         case '851':
9584                         case 'cp851':
9585                         case 'csibm851':
9586                         case 'ibm851':
9587                                 return 'IBM851';
9588
9589                         case '852':
9590                         case 'cp852':
9591                         case 'cspcp852':
9592                         case 'ibm852':
9593                                 return 'IBM852';
9594
9595                         case '855':
9596                         case 'cp855':
9597                         case 'csibm855':
9598                         case 'ibm855':
9599                                 return 'IBM855';
9600
9601                         case '857':
9602                         case 'cp857':
9603                         case 'csibm857':
9604                         case 'ibm857':
9605                                 return 'IBM857';
9606
9607                         case '860':
9608                         case 'cp860':
9609                         case 'csibm860':
9610                         case 'ibm860':
9611                                 return 'IBM860';
9612
9613                         case '861':
9614                         case 'cpis':
9615                         case 'cp861':
9616                         case 'csibm861':
9617                         case 'ibm861':
9618                                 return 'IBM861';
9619
9620                         case '862':
9621                         case 'cp862':
9622                         case 'cspc862latinhebrew':
9623                         case 'ibm862':
9624                                 return 'IBM862';
9625
9626                         case '863':
9627                         case 'cp863':
9628                         case 'csibm863':
9629                         case 'ibm863':
9630                                 return 'IBM863';
9631
9632                         case 'cp864':
9633                         case 'csibm864':
9634                         case 'ibm864':
9635                                 return 'IBM864';
9636
9637                         case '865':
9638                         case 'cp865':
9639                         case 'csibm865':
9640                         case 'ibm865':
9641                                 return 'IBM865';
9642
9643                         case '866':
9644                         case 'cp866':
9645                         case 'csibm866':
9646                         case 'ibm866':
9647                                 return 'IBM866';
9648
9649                         case 'cpar':
9650                         case 'cp868':
9651                         case 'csibm868':
9652                         case 'ibm868':
9653                                 return 'IBM868';
9654
9655                         case '869':
9656                         case 'cpgr':
9657                         case 'cp869':
9658                         case 'csibm869':
9659                         case 'ibm869':
9660                                 return 'IBM869';
9661
9662                         case 'cp870':
9663                         case 'csibm870':
9664                         case 'ebcdiccproece':
9665                         case 'ebcdiccpyu':
9666                         case 'ibm870':
9667                                 return 'IBM870';
9668
9669                         case 'cp871':
9670                         case 'csibm871':
9671                         case 'ebcdiccpis':
9672                         case 'ibm871':
9673                                 return 'IBM871';
9674
9675                         case 'cp880':
9676                         case 'csibm880':
9677                         case 'ebcdiccyrillic':
9678                         case 'ibm880':
9679                                 return 'IBM880';
9680
9681                         case 'cp891':
9682                         case 'csibm891':
9683                         case 'ibm891':
9684                                 return 'IBM891';
9685
9686                         case 'cp903':
9687                         case 'csibm903':
9688                         case 'ibm903':
9689                                 return 'IBM903';
9690
9691                         case '904':
9692                         case 'cp904':
9693                         case 'csibbm904':
9694                         case 'ibm904':
9695                                 return 'IBM904';
9696
9697                         case 'cp905':
9698                         case 'csibm905':
9699                         case 'ebcdiccptr':
9700                         case 'ibm905':
9701                                 return 'IBM905';
9702
9703                         case 'cp918':
9704                         case 'csibm918':
9705                         case 'ebcdiccpar2':
9706                         case 'ibm918':
9707                                 return 'IBM918';
9708
9709                         case 'cp1026':
9710                         case 'csibm1026':
9711                         case 'ibm1026':
9712                                 return 'IBM1026';
9713
9714                         case 'ibm1047':
9715                         case 'ibm1047':
9716                                 return 'IBM1047';
9717
9718                         case 'csiso143iecp271':
9719                         case 'iecp271':
9720                         case 'isoir143':
9721                                 return 'IEC_P27-1';
9722
9723                         case 'csiso49inis':
9724                         case 'inis':
9725                         case 'isoir49':
9726                                 return 'INIS';
9727
9728                         case 'csiso50inis8':
9729                         case 'inis8':
9730                         case 'isoir50':
9731                                 return 'INIS-8';
9732
9733                         case 'csiso51iniscyrillic':
9734                         case 'iniscyrillic':
9735                         case 'isoir51':
9736                                 return 'INIS-cyrillic';
9737
9738                         case 'csinvariant':
9739                         case 'invariant':
9740                                 return 'INVARIANT';
9741
9742                         case 'iso2022cn':
9743                                 return 'ISO-2022-CN';
9744
9745                         case 'iso2022cnext':
9746                                 return 'ISO-2022-CN-EXT';
9747
9748                         case 'csiso2022jp':
9749                         case 'iso2022jp':
9750                                 return 'ISO-2022-JP';
9751
9752                         case 'csiso2022jp2':
9753                         case 'iso2022jp2':
9754                                 return 'ISO-2022-JP-2';
9755
9756                         case 'csiso2022kr':
9757                         case 'iso2022kr':
9758                                 return 'ISO-2022-KR';
9759
9760                         case 'cswindows30latin1':
9761                         case 'iso88591windows30latin1':
9762                                 return 'ISO-8859-1-Windows-3.0-Latin-1';
9763
9764                         case 'cswindows31latin1':
9765                         case 'iso88591windows31latin1':
9766                                 return 'ISO-8859-1-Windows-3.1-Latin-1';
9767
9768                         case 'csisolatin2':
9769                         case 'iso88592':
9770                         case 'isoir101':
9771                         case 'iso88592':
9772                         case 'iso885921987':
9773                         case 'l2':
9774                         case 'latin2':
9775                                 return 'ISO-8859-2';
9776
9777                         case 'cswindows31latin2':
9778                         case 'iso88592windowslatin2':
9779                                 return 'ISO-8859-2-Windows-Latin-2';
9780
9781                         case 'csisolatin3':
9782                         case 'iso88593':
9783                         case 'isoir109':
9784                         case 'iso88593':
9785                         case 'iso885931988':
9786                         case 'l3':
9787                         case 'latin3':
9788                                 return 'ISO-8859-3';
9789
9790                         case 'csisolatin4':
9791                         case 'iso88594':
9792                         case 'isoir110':
9793                         case 'iso88594':
9794                         case 'iso885941988':
9795                         case 'l4':
9796                         case 'latin4':
9797                                 return 'ISO-8859-4';
9798
9799                         case 'csisolatincyrillic':
9800                         case 'cyrillic':
9801                         case 'iso88595':
9802                         case 'isoir144':
9803                         case 'iso88595':
9804                         case 'iso885951988':
9805                                 return 'ISO-8859-5';
9806
9807                         case 'arabic':
9808                         case 'asmo708':
9809                         case 'csisolatinarabic':
9810                         case 'ecma114':
9811                         case 'iso88596':
9812                         case 'isoir127':
9813                         case 'iso88596':
9814                         case 'iso885961987':
9815                                 return 'ISO-8859-6';
9816
9817                         case 'csiso88596e':
9818                         case 'iso88596e':
9819                         case 'iso88596e':
9820                                 return 'ISO-8859-6-E';
9821
9822                         case 'csiso88596i':
9823                         case 'iso88596i':
9824                         case 'iso88596i':
9825                                 return 'ISO-8859-6-I';
9826
9827                         case 'csisolatingreek':
9828                         case 'ecma118':
9829                         case 'elot928':
9830                         case 'greek':
9831                         case 'greek8':
9832                         case 'iso88597':
9833                         case 'isoir126':
9834                         case 'iso88597':
9835                         case 'iso885971987':
9836                                 return 'ISO-8859-7';
9837
9838                         case 'csisolatinhebrew':
9839                         case 'hebrew':
9840                         case 'iso88598':
9841                         case 'isoir138':
9842                         case 'iso88598':
9843                         case 'iso885981988':
9844                                 return 'ISO-8859-8';
9845
9846                         case 'csiso88598e':
9847                         case 'iso88598e':
9848                         case 'iso88598e':
9849                                 return 'ISO-8859-8-E';
9850
9851                         case 'csiso88598i':
9852                         case 'iso88598i':
9853                         case 'iso88598i':
9854                                 return 'ISO-8859-8-I';
9855
9856                         case 'cswindows31latin5':
9857                         case 'iso88599windowslatin5':
9858                                 return 'ISO-8859-9-Windows-Latin-5';
9859
9860                         case 'csisolatin6':
9861                         case 'iso885910':
9862                         case 'isoir157':
9863                         case 'iso8859101992':
9864                         case 'l6':
9865                         case 'latin6':
9866                                 return 'ISO-8859-10';
9867
9868                         case 'iso885913':
9869                                 return 'ISO-8859-13';
9870
9871                         case 'iso885914':
9872                         case 'isoceltic':
9873                         case 'isoir199':
9874                         case 'iso885914':
9875                         case 'iso8859141998':
9876                         case 'l8':
9877                         case 'latin8':
9878                                 return 'ISO-8859-14';
9879
9880                         case 'iso885915':
9881                         case 'iso885915':
9882                         case 'latin9':
9883                                 return 'ISO-8859-15';
9884
9885                         case 'iso885916':
9886                         case 'isoir226':
9887                         case 'iso885916':
9888                         case 'iso8859162001':
9889                         case 'l10':
9890                         case 'latin10':
9891                                 return 'ISO-8859-16';
9892
9893                         case 'iso10646j1':
9894                                 return 'ISO-10646-J-1';
9895
9896                         case 'csunicode':
9897                         case 'iso10646ucs2':
9898                                 return 'ISO-10646-UCS-2';
9899
9900                         case 'csucs4':
9901                         case 'iso10646ucs4':
9902                                 return 'ISO-10646-UCS-4';
9903
9904                         case 'csunicodeascii':
9905                         case 'iso10646ucsbasic':
9906                                 return 'ISO-10646-UCS-Basic';
9907
9908                         case 'csunicodelatin1':
9909                         case 'iso10646':
9910                         case 'iso10646unicodelatin1':
9911                                 return 'ISO-10646-Unicode-Latin1';
9912
9913                         case 'csiso10646utf1':
9914                         case 'iso10646utf1':
9915                                 return 'ISO-10646-UTF-1';
9916
9917                         case 'csiso115481':
9918                         case 'iso115481':
9919                         case 'iso115481':
9920                         case 'isotr115481':
9921                                 return 'ISO-11548-1';
9922
9923                         case 'csiso90':
9924                         case 'isoir90':
9925                                 return 'iso-ir-90';
9926
9927                         case 'csunicodeibm1261':
9928                         case 'isounicodeibm1261':
9929                                 return 'ISO-Unicode-IBM-1261';
9930
9931                         case 'csunicodeibm1264':
9932                         case 'isounicodeibm1264':
9933                                 return 'ISO-Unicode-IBM-1264';
9934
9935                         case 'csunicodeibm1265':
9936                         case 'isounicodeibm1265':
9937                                 return 'ISO-Unicode-IBM-1265';
9938
9939                         case 'csunicodeibm1268':
9940                         case 'isounicodeibm1268':
9941                                 return 'ISO-Unicode-IBM-1268';
9942
9943                         case 'csunicodeibm1276':
9944                         case 'isounicodeibm1276':
9945                                 return 'ISO-Unicode-IBM-1276';
9946
9947                         case 'csiso646basic1983':
9948                         case 'iso646basic1983':
9949                         case 'ref':
9950                                 return 'ISO_646.basic:1983';
9951
9952                         case 'csiso2intlrefversion':
9953                         case 'irv':
9954                         case 'isoir2':
9955                         case 'iso646irv1983':
9956                                 return 'ISO_646.irv:1983';
9957
9958                         case 'csiso2033':
9959                         case 'e13b':
9960                         case 'isoir98':
9961                         case 'iso20331983':
9962                                 return 'ISO_2033-1983';
9963
9964                         case 'csiso5427cyrillic':
9965                         case 'isoir37':
9966                         case 'iso5427':
9967                                 return 'ISO_5427';
9968
9969                         case 'isoir54':
9970                         case 'iso5427cyrillic1981':
9971                         case 'iso54271981':
9972                                 return 'ISO_5427:1981';
9973
9974                         case 'csiso5428greek':
9975                         case 'isoir55':
9976                         case 'iso54281980':
9977                                 return 'ISO_5428:1980';
9978
9979                         case 'csiso6937add':
9980                         case 'isoir152':
9981                         case 'iso6937225':
9982                                 return 'ISO_6937-2-25';
9983
9984                         case 'csisotextcomm':
9985                         case 'isoir142':
9986                         case 'iso69372add':
9987                                 return 'ISO_6937-2-add';
9988
9989                         case 'csiso8859supp':
9990                         case 'isoir154':
9991                         case 'iso8859supp':
9992                         case 'latin125':
9993                                 return 'ISO_8859-supp';
9994
9995                         case 'csiso10367box':
9996                         case 'isoir155':
9997                         case 'iso10367box':
9998                                 return 'ISO_10367-box';
9999
10000                         case 'csiso15italian':
10001                         case 'isoir15':
10002                         case 'iso646it':
10003                         case 'it':
10004                                 return 'IT';
10005
10006                         case 'csiso13jisc6220jp':
10007                         case 'isoir13':
10008                         case 'jisc62201969':
10009                         case 'jisc62201969jp':
10010                         case 'katakana':
10011                         case 'x02017':
10012                                 return 'JIS_C6220-1969-jp';
10013
10014                         case 'csiso14jisc6220ro':
10015                         case 'isoir14':
10016                         case 'iso646jp':
10017                         case 'jisc62201969ro':
10018                         case 'jp':
10019                                 return 'JIS_C6220-1969-ro';
10020
10021                         case 'csiso42jisc62261978':
10022                         case 'isoir42':
10023                         case 'jisc62261978':
10024                                 return 'JIS_C6226-1978';
10025
10026                         case 'csiso87jisx0208':
10027                         case 'isoir87':
10028                         case 'jisc62261983':
10029                         case 'jisx02081983':
10030                         case 'x0208':
10031                                 return 'JIS_C6226-1983';
10032
10033                         case 'csiso91jisc62291984a':
10034                         case 'isoir91':
10035                         case 'jisc62291984a':
10036                         case 'jpocra':
10037                                 return 'JIS_C6229-1984-a';
10038
10039                         case 'csiso92jisc62991984b':
10040                         case 'isoir92':
10041                         case 'iso646jpocrb':
10042                         case 'jisc62291984b':
10043                         case 'jpocrb':
10044                                 return 'JIS_C6229-1984-b';
10045
10046                         case 'csiso93jis62291984badd':
10047                         case 'isoir93':
10048                         case 'jisc62291984badd':
10049                         case 'jpocrbadd':
10050                                 return 'JIS_C6229-1984-b-add';
10051
10052                         case 'csiso94jis62291984hand':
10053                         case 'isoir94':
10054                         case 'jisc62291984hand':
10055                         case 'jpocrhand':
10056                                 return 'JIS_C6229-1984-hand';
10057
10058                         case 'csiso95jis62291984handadd':
10059                         case 'isoir95':
10060                         case 'jisc62291984handadd':
10061                         case 'jpocrhandadd':
10062                                 return 'JIS_C6229-1984-hand-add';
10063
10064                         case 'csiso96jisc62291984kana':
10065                         case 'isoir96':
10066                         case 'jisc62291984kana':
10067                                 return 'JIS_C6229-1984-kana';
10068
10069                         case 'csjisencoding':
10070                         case 'jisencoding':
10071                                 return 'JIS_Encoding';
10072
10073                         case 'cshalfwidthkatakana':
10074                         case 'jisx0201':
10075                         case 'x0201':
10076                                 return 'JIS_X0201';
10077
10078                         case 'csiso159jisx02121990':
10079                         case 'isoir159':
10080                         case 'jisx02121990':
10081                         case 'x0212':
10082                                 return 'JIS_X0212-1990';
10083
10084                         case 'csiso141jusib1002':
10085                         case 'isoir141':
10086                         case 'iso646yu':
10087                         case 'js':
10088                         case 'jusib1002':
10089                         case 'yu':
10090                                 return 'JUS_I.B1.002';
10091
10092                         case 'csiso147macedonian':
10093                         case 'isoir147':
10094                         case 'jusib1003mac':
10095                         case 'macedonian':
10096                                 return 'JUS_I.B1.003-mac';
10097
10098                         case 'csiso146serbian':
10099                         case 'isoir146':
10100                         case 'jusib1003serb':
10101                         case 'serbian':
10102                                 return 'JUS_I.B1.003-serb';
10103
10104                         case 'koi7switched':
10105                                 return 'KOI7-switched';
10106
10107                         case 'cskoi8r':
10108                         case 'koi8r':
10109                                 return 'KOI8-R';
10110
10111                         case 'koi8u':
10112                                 return 'KOI8-U';
10113
10114                         case 'csksc5636':
10115                         case 'iso646kr':
10116                         case 'ksc5636':
10117                                 return 'KSC5636';
10118
10119                         case 'cskz1048':
10120                         case 'kz1048':
10121                         case 'rk1048':
10122                         case 'strk10482002':
10123                                 return 'KZ-1048';
10124
10125                         case 'csiso19latingreek':
10126                         case 'isoir19':
10127                         case 'latingreek':
10128                                 return 'latin-greek';
10129
10130                         case 'csiso27latingreek1':
10131                         case 'isoir27':
10132                         case 'latingreek1':
10133                                 return 'Latin-greek-1';
10134
10135                         case 'csiso158lap':
10136                         case 'isoir158':
10137                         case 'lap':
10138                         case 'latinlap':
10139                                 return 'latin-lap';
10140
10141                         case 'csmacintosh':
10142                         case 'mac':
10143                         case 'macintosh':
10144                                 return 'macintosh';
10145
10146                         case 'csmicrosoftpublishing':
10147                         case 'microsoftpublishing':
10148                                 return 'Microsoft-Publishing';
10149
10150                         case 'csmnem':
10151                         case 'mnem':
10152                                 return 'MNEM';
10153
10154                         case 'csmnemonic':
10155                         case 'mnemonic':
10156                                 return 'MNEMONIC';
10157
10158                         case 'csiso86hungarian':
10159                         case 'hu':
10160                         case 'isoir86':
10161                         case 'iso646hu':
10162                         case 'msz77953':
10163                                 return 'MSZ_7795.3';
10164
10165                         case 'csnatsdano':
10166                         case 'isoir91':
10167                         case 'natsdano':
10168                                 return 'NATS-DANO';
10169
10170                         case 'csnatsdanoadd':
10171                         case 'isoir92':
10172                         case 'natsdanoadd':
10173                                 return 'NATS-DANO-ADD';
10174
10175                         case 'csnatssefi':
10176                         case 'isoir81':
10177                         case 'natssefi':
10178                                 return 'NATS-SEFI';
10179
10180                         case 'csnatssefiadd':
10181                         case 'isoir82':
10182                         case 'natssefiadd':
10183                                 return 'NATS-SEFI-ADD';
10184
10185                         case 'csiso151cuba':
10186                         case 'cuba':
10187                         case 'isoir151':
10188                         case 'iso646cu':
10189                         case 'ncnc001081':
10190                                 return 'NC_NC00-10:81';
10191
10192                         case 'csiso69french':
10193                         case 'fr':
10194                         case 'isoir69':
10195                         case 'iso646fr':
10196                         case 'nfz62010':
10197                                 return 'NF_Z_62-010';
10198
10199                         case 'csiso25french':
10200                         case 'isoir25':
10201                         case 'iso646fr1':
10202                         case 'nfz620101973':
10203                                 return 'NF_Z_62-010_(1973)';
10204
10205                         case 'csiso60danishnorwegian':
10206                         case 'csiso60norwegian1':
10207                         case 'isoir60':
10208                         case 'iso646no':
10209                         case 'no':
10210                         case 'ns45511':
10211                                 return 'NS_4551-1';
10212
10213                         case 'csiso61norwegian2':
10214                         case 'isoir61':
10215                         case 'iso646no2':
10216                         case 'no2':
10217                         case 'ns45512':
10218                                 return 'NS_4551-2';
10219
10220                         case 'osdebcdicdf03irv':
10221                                 return 'OSD_EBCDIC_DF03_IRV';
10222
10223                         case 'osdebcdicdf041':
10224                                 return 'OSD_EBCDIC_DF04_1';
10225
10226                         case 'osdebcdicdf0415':
10227                                 return 'OSD_EBCDIC_DF04_15';
10228
10229                         case 'cspc8danishnorwegian':
10230                         case 'pc8danishnorwegian':
10231                                 return 'PC8-Danish-Norwegian';
10232
10233                         case 'cspc8turkish':
10234                         case 'pc8turkish':
10235                                 return 'PC8-Turkish';
10236
10237                         case 'csiso16portuguese':
10238                         case 'isoir16':
10239                         case 'iso646pt':
10240                         case 'pt':
10241                                 return 'PT';
10242
10243                         case 'csiso84portuguese2':
10244                         case 'isoir84':
10245                         case 'iso646pt2':
10246                         case 'pt2':
10247                                 return 'PT2';
10248
10249                         case 'cp154':
10250                         case 'csptcp154':
10251                         case 'cyrillicasian':
10252                         case 'pt154':
10253                         case 'ptcp154':
10254                                 return 'PTCP154';
10255
10256                         case 'scsu':
10257                                 return 'SCSU';
10258
10259                         case 'csiso10swedish':
10260                         case 'fi':
10261                         case 'isoir10':
10262                         case 'iso646fi':
10263                         case 'iso646se':
10264                         case 'se':
10265                         case 'sen850200b':
10266                                 return 'SEN_850200_B';
10267
10268                         case 'csiso11swedishfornames':
10269                         case 'isoir11':
10270                         case 'iso646se2':
10271                         case 'se2':
10272                         case 'sen850200c':
10273                                 return 'SEN_850200_C';
10274
10275                         case 'csshiftjis':
10276                         case 'mskanji':
10277                         case 'shiftjis':
10278                                 return 'Shift_JIS';
10279
10280                         case 'csiso102t617bit':
10281                         case 'isoir102':
10282                         case 't617bit':
10283                                 return 'T.61-7bit';
10284
10285                         case 'csiso103t618bit':
10286                         case 'isoir103':
10287                         case 't61':
10288                         case 't618bit':
10289                                 return 'T.61-8bit';
10290
10291                         case 'csiso128t101g2':
10292                         case 'isoir128':
10293                         case 't101g2':
10294                                 return 'T.101-G2';
10295
10296                         case 'cstscii':
10297                         case 'tscii':
10298                                 return 'TSCII';
10299
10300                         case 'csunicode11':
10301                         case 'unicode11':
10302                                 return 'UNICODE-1-1';
10303
10304                         case 'csunicode11utf7':
10305                         case 'unicode11utf7':
10306                                 return 'UNICODE-1-1-UTF-7';
10307
10308                         case 'csunknown8bit':
10309                         case 'unknown8bit':
10310                                 return 'UNKNOWN-8BIT';
10311
10312                         case 'ansix341968':
10313                         case 'ansix341986':
10314                         case 'ascii':
10315                         case 'cp367':
10316                         case 'csascii':
10317                         case 'ibm367':
10318                         case 'isoir6':
10319                         case 'iso646us':
10320                         case 'iso646irv1991':
10321                         case 'us':
10322                         case 'usascii':
10323                                 return 'US-ASCII';
10324
10325                         case 'csusdk':
10326                         case 'usdk':
10327                                 return 'us-dk';
10328
10329                         case 'utf7':
10330                                 return 'UTF-7';
10331
10332                         case 'utf8':
10333                                 return 'UTF-8';
10334
10335                         case 'utf16':
10336                                 return 'UTF-16';
10337
10338                         case 'utf16be':
10339                                 return 'UTF-16BE';
10340
10341                         case 'utf16le':
10342                                 return 'UTF-16LE';
10343
10344                         case 'utf32':
10345                                 return 'UTF-32';
10346
10347                         case 'utf32be':
10348                                 return 'UTF-32BE';
10349
10350                         case 'utf32le':
10351                                 return 'UTF-32LE';
10352
10353                         case 'csventurainternational':
10354                         case 'venturainternational':
10355                                 return 'Ventura-International';
10356
10357                         case 'csventuramath':
10358                         case 'venturamath':
10359                                 return 'Ventura-Math';
10360
10361                         case 'csventuraus':
10362                         case 'venturaus':
10363                                 return 'Ventura-US';
10364
10365                         case 'csiso70videotexsupp1':
10366                         case 'isoir70':
10367                         case 'videotexsuppl':
10368                                 return 'videotex-suppl';
10369
10370                         case 'csviqr':
10371                         case 'viqr':
10372                                 return 'VIQR';
10373
10374                         case 'csviscii':
10375                         case 'viscii':
10376                                 return 'VISCII';
10377
10378                         case 'cswindows31j':
10379                         case 'windows31j':
10380                                 return 'Windows-31J';
10381
10382                         case 'iso885911':
10383                         case 'tis620':
10384                                 return 'Windows-874';
10385
10386                         case 'cseuckr':
10387                         case 'euckr':
10388                         case 'windows949':
10389                         case 'csksc56011987':
10390                         case 'isoir149':
10391                         case 'korean':
10392                         case 'ksc5601':
10393                         case 'ksc56011987':
10394                         case 'ksc56011989':
10395                                 return 'Windows-949';
10396
10397                         case 'windows1250':
10398                                 return 'windows-1250';
10399
10400                         case 'windows1251':
10401                                 return 'windows-1251';
10402
10403                         case 'cp819':
10404                         case 'csisolatin1':
10405                         case 'ibm819':
10406                         case 'iso88591':
10407                         case 'isoir100':
10408                         case 'iso885911987':
10409                         case 'l1':
10410                         case 'latin1':
10411                         case 'windows1252':
10412                                 return 'Windows-1252';
10413
10414                         case 'windows1252':
10415                                 return 'windows-1252';
10416
10417                         case 'windows1253':
10418                                 return 'windows-1253';
10419
10420                         case 'csisolatin5':
10421                         case 'iso88599':
10422                         case 'isoir148':
10423                         case 'iso885991989':
10424                         case 'l5':
10425                         case 'latin5':
10426                         case 'windows1254':
10427                                 return 'Windows-1254';
10428
10429                         case 'windows1254':
10430                                 return 'windows-1254';
10431
10432                         case 'windows1255':
10433                                 return 'windows-1255';
10434
10435                         case 'windows1256':
10436                                 return 'windows-1256';
10437
10438                         case 'windows1257':
10439                                 return 'windows-1257';
10440
10441                         case 'windows1258':
10442                                 return 'windows-1258';
10443
10444                         default:
10445                                 return $charset;
10446                 }
10447         }
10448
10449         function get_curl_version()
10450         {
10451                 if (is_array($curl = curl_version()))
10452                 {
10453                         $curl = $curl['version'];
10454                 }
10455                 elseif (substr($curl, 0, 5) == 'curl/')
10456                 {
10457                         $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10458                 }
10459                 elseif (substr($curl, 0, 8) == 'libcurl/')
10460                 {
10461                         $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10462                 }
10463                 else
10464                 {
10465                         $curl = 0;
10466                 }
10467                 return $curl;
10468         }
10469
10470         function is_subclass_of($class1, $class2)
10471         {
10472                 if (func_num_args() != 2)
10473                 {
10474                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10475                 }
10476                 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10477                 {
10478                         return is_subclass_of($class1, $class2);
10479                 }
10480                 elseif (is_string($class1) && is_string($class2))
10481                 {
10482                         if (class_exists($class1))
10483                         {
10484                                 if (class_exists($class2))
10485                                 {
10486                                         $class2 = strtolower($class2);
10487                                         while ($class1 = strtolower(get_parent_class($class1)))
10488                                         {
10489                                                 if ($class1 == $class2)
10490                                                 {
10491                                                         return true;
10492                                                 }
10493                                         }
10494                                 }
10495                         }
10496                         else
10497                         {
10498                                 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10499                         }
10500                 }
10501                 return false;
10502         }
10503
10504         /**
10505          * Strip HTML comments
10506          *
10507          * @access public
10508          * @param string $data Data to strip comments from
10509          * @return string Comment stripped string
10510          */
10511         function strip_comments($data)
10512         {
10513                 $output = '';
10514                 while (($start = strpos($data, '<!--')) !== false)
10515                 {
10516                         $output .= substr($data, 0, $start);
10517                         if (($end = strpos($data, '-->', $start)) !== false)
10518                         {
10519                                 $data = substr_replace($data, '', 0, $end + 3);
10520                         }
10521                         else
10522                         {
10523                                 $data = '';
10524                         }
10525                 }
10526                 return $output . $data;
10527         }
10528
10529         function parse_date($dt)
10530         {
10531                 $parser = SimplePie_Parse_Date::get();
10532                 return $parser->parse($dt);
10533         }
10534
10535         /**
10536          * Decode HTML entities
10537          *
10538          * @static
10539          * @access public
10540          * @param string $data Input data
10541          * @return string Output data
10542          */
10543         function entities_decode($data)
10544         {
10545                 $decoder =& new SimplePie_Decode_HTML_Entities($data);
10546                 return $decoder->parse();
10547         }
10548
10549         /**
10550          * Remove RFC822 comments
10551          *
10552          * @access public
10553          * @param string $data Data to strip comments from
10554          * @return string Comment stripped string
10555          */
10556         function uncomment_rfc822($string)
10557         {
10558                 $string = (string) $string;
10559                 $position = 0;
10560                 $length = strlen($string);
10561                 $depth = 0;
10562
10563                 $output = '';
10564
10565                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10566                 {
10567                         $output .= substr($string, $position, $pos - $position);
10568                         $position = $pos + 1;
10569                         if ($string[$pos - 1] !== '\\')
10570                         {
10571                                 $depth++;
10572                                 while ($depth && $position < $length)
10573                                 {
10574                                         $position += strcspn($string, '()', $position);
10575                                         if ($string[$position - 1] === '\\')
10576                                         {
10577                                                 $position++;
10578                                                 continue;
10579                                         }
10580                                         elseif (isset($string[$position]))
10581                                         {
10582                                                 switch ($string[$position])
10583                                                 {
10584                                                         case '(':
10585                                                                 $depth++;
10586                                                                 break;
10587
10588                                                         case ')':
10589                                                                 $depth--;
10590                                                                 break;
10591                                                 }
10592                                                 $position++;
10593                                         }
10594                                         else
10595                                         {
10596                                                 break;
10597                                         }
10598                                 }
10599                         }
10600                         else
10601                         {
10602                                 $output .= '(';
10603                         }
10604                 }
10605                 $output .= substr($string, $position);
10606
10607                 return $output;
10608         }
10609
10610         function parse_mime($mime)
10611         {
10612                 if (($pos = strpos($mime, ';')) === false)
10613                 {
10614                         return trim($mime);
10615                 }
10616                 else
10617                 {
10618                         return trim(substr($mime, 0, $pos));
10619                 }
10620         }
10621
10622         function htmlspecialchars_decode($string, $quote_style)
10623         {
10624                 if (function_exists('htmlspecialchars_decode'))
10625                 {
10626                         return htmlspecialchars_decode($string, $quote_style);
10627                 }
10628                 else
10629                 {
10630                         return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10631                 }
10632         }
10633
10634         function atom_03_construct_type($attribs)
10635         {
10636                 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10637                 {
10638                         $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10639                 }
10640                 else
10641                 {
10642                         $mode = SIMPLEPIE_CONSTRUCT_NONE;
10643                 }
10644                 if (isset($attribs['']['type']))
10645                 {
10646                         switch (strtolower(trim($attribs['']['type'])))
10647                         {
10648                                 case 'text':
10649                                 case 'text/plain':
10650                                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10651
10652                                 case 'html':
10653                                 case 'text/html':
10654                                         return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10655
10656                                 case 'xhtml':
10657                                 case 'application/xhtml+xml':
10658                                         return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10659
10660                                 default:
10661                                         return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10662                         }
10663                 }
10664                 else
10665                 {
10666                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10667                 }
10668         }
10669
10670         function atom_10_construct_type($attribs)
10671         {
10672                 if (isset($attribs['']['type']))
10673                 {
10674                         switch (strtolower(trim($attribs['']['type'])))
10675                         {
10676                                 case 'text':
10677                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10678
10679                                 case 'html':
10680                                         return SIMPLEPIE_CONSTRUCT_HTML;
10681
10682                                 case 'xhtml':
10683                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10684
10685                                 default:
10686                                         return SIMPLEPIE_CONSTRUCT_NONE;
10687                         }
10688                 }
10689                 return SIMPLEPIE_CONSTRUCT_TEXT;
10690         }
10691
10692         function atom_10_content_construct_type($attribs)
10693         {
10694                 if (isset($attribs['']['type']))
10695                 {
10696                         $type = strtolower(trim($attribs['']['type']));
10697                         switch ($type)
10698                         {
10699                                 case 'text':
10700                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10701
10702                                 case 'html':
10703                                         return SIMPLEPIE_CONSTRUCT_HTML;
10704
10705                                 case 'xhtml':
10706                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10707                         }
10708                         if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10709                         {
10710                                 return SIMPLEPIE_CONSTRUCT_NONE;
10711                         }
10712                         else
10713                         {
10714                                 return SIMPLEPIE_CONSTRUCT_BASE64;
10715                         }
10716                 }
10717                 else
10718                 {
10719                         return SIMPLEPIE_CONSTRUCT_TEXT;
10720                 }
10721         }
10722
10723         function is_isegment_nz_nc($string)
10724         {
10725                 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);
10726         }
10727
10728         function space_seperated_tokens($string)
10729         {
10730                 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10731                 $string_length = strlen($string);
10732
10733                 $position = strspn($string, $space_characters);
10734                 $tokens = array();
10735
10736                 while ($position < $string_length)
10737                 {
10738                         $len = strcspn($string, $space_characters, $position);
10739                         $tokens[] = substr($string, $position, $len);
10740                         $position += $len;
10741                         $position += strspn($string, $space_characters, $position);
10742                 }
10743
10744                 return $tokens;
10745         }
10746
10747         function array_unique($array)
10748         {
10749                 if (version_compare(PHP_VERSION, '5.2', '>='))
10750                 {
10751                         return array_unique($array);
10752                 }
10753                 else
10754                 {
10755                         $array = (array) $array;
10756                         $new_array = array();
10757                         $new_array_strings = array();
10758                         foreach ($array as $key => $value)
10759                         {
10760                                 if (is_object($value))
10761                                 {
10762                                         if (method_exists($value, '__toString'))
10763                                         {
10764                                                 $cmp = $value->__toString();
10765                                         }
10766                                         else
10767                                         {
10768                                                 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10769                                         }
10770                                 }
10771                                 elseif (is_array($value))
10772                                 {
10773                                         $cmp = (string) reset($value);
10774                                 }
10775                                 else
10776                                 {
10777                                         $cmp = (string) $value;
10778                                 }
10779                                 if (!in_array($cmp, $new_array_strings))
10780                                 {
10781                                         $new_array[$key] = $value;
10782                                         $new_array_strings[] = $cmp;
10783                                 }
10784                         }
10785                         return $new_array;
10786                 }
10787         }
10788
10789         /**
10790          * Converts a unicode codepoint to a UTF-8 character
10791          *
10792          * @static
10793          * @access public
10794          * @param int $codepoint Unicode codepoint
10795          * @return string UTF-8 character
10796          */
10797         function codepoint_to_utf8($codepoint)
10798         {
10799                 $codepoint = (int) $codepoint;
10800                 if ($codepoint < 0)
10801                 {
10802                         return false;
10803                 }
10804                 else if ($codepoint <= 0x7f)
10805                 {
10806                         return chr($codepoint);
10807                 }
10808                 else if ($codepoint <= 0x7ff)
10809                 {
10810                         return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10811                 }
10812                 else if ($codepoint <= 0xffff)
10813                 {
10814                         return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10815                 }
10816                 else if ($codepoint <= 0x10ffff)
10817                 {
10818                         return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10819                 }
10820                 else
10821                 {
10822                         // U+FFFD REPLACEMENT CHARACTER
10823                         return "\xEF\xBF\xBD";
10824                 }
10825         }
10826
10827         /**
10828          * Re-implementation of PHP 5's stripos()
10829          *
10830          * Returns the numeric position of the first occurrence of needle in the
10831          * haystack string.
10832          *
10833          * @static
10834          * @access string
10835          * @param object $haystack
10836          * @param string $needle Note that the needle may be a string of one or more
10837          *     characters. If needle is not a string, it is converted to an integer
10838          *     and applied as the ordinal value of a character.
10839          * @param int $offset The optional offset parameter allows you to specify which
10840          *     character in haystack to start searching. The position returned is still
10841          *     relative to the beginning of haystack.
10842          * @return bool If needle is not found, stripos() will return boolean false.
10843          */
10844         function stripos($haystack, $needle, $offset = 0)
10845         {
10846                 if (function_exists('stripos'))
10847                 {
10848                         return stripos($haystack, $needle, $offset);
10849                 }
10850                 else
10851                 {
10852                         if (is_string($needle))
10853                         {
10854                                 $needle = strtolower($needle);
10855                         }
10856                         elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10857                         {
10858                                 $needle = strtolower(chr($needle));
10859                         }
10860                         else
10861                         {
10862                                 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10863                                 return false;
10864                         }
10865
10866                         return strpos(strtolower($haystack), $needle, $offset);
10867                 }
10868         }
10869
10870         /**
10871          * Similar to parse_str()
10872          *
10873          * Returns an associative array of name/value pairs, where the value is an
10874          * array of values that have used the same name
10875          *
10876          * @static
10877          * @access string
10878          * @param string $str The input string.
10879          * @return array
10880          */
10881         function parse_str($str)
10882         {
10883                 $return = array();
10884                 $str = explode('&', $str);
10885
10886                 foreach ($str as $section)
10887                 {
10888                         if (strpos($section, '=') !== false)
10889                         {
10890                                 list($name, $value) = explode('=', $section, 2);
10891                                 $return[urldecode($name)][] = urldecode($value);
10892                         }
10893                         else
10894                         {
10895                                 $return[urldecode($section)][] = null;
10896                         }
10897                 }
10898
10899                 return $return;
10900         }
10901
10902         /**
10903          * Detect XML encoding, as per XML 1.0 Appendix F.1
10904          *
10905          * @todo Add support for EBCDIC
10906          * @param string $data XML data
10907          * @return array Possible encodings
10908          */
10909         function xml_encoding($data)
10910         {
10911                 // UTF-32 Big Endian BOM
10912                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10913                 {
10914                         $encoding[] = 'UTF-32BE';
10915                 }
10916                 // UTF-32 Little Endian BOM
10917                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10918                 {
10919                         $encoding[] = 'UTF-32LE';
10920                 }
10921                 // UTF-16 Big Endian BOM
10922                 elseif (substr($data, 0, 2) === "\xFE\xFF")
10923                 {
10924                         $encoding[] = 'UTF-16BE';
10925                 }
10926                 // UTF-16 Little Endian BOM
10927                 elseif (substr($data, 0, 2) === "\xFF\xFE")
10928                 {
10929                         $encoding[] = 'UTF-16LE';
10930                 }
10931                 // UTF-8 BOM
10932                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10933                 {
10934                         $encoding[] = 'UTF-8';
10935                 }
10936                 // UTF-32 Big Endian Without BOM
10937                 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")
10938                 {
10939                         if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10940                         {
10941                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10942                                 if ($parser->parse())
10943                                 {
10944                                         $encoding[] = $parser->encoding;
10945                                 }
10946                         }
10947                         $encoding[] = 'UTF-32BE';
10948                 }
10949                 // UTF-32 Little Endian Without BOM
10950                 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")
10951                 {
10952                         if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10953                         {
10954                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10955                                 if ($parser->parse())
10956                                 {
10957                                         $encoding[] = $parser->encoding;
10958                                 }
10959                         }
10960                         $encoding[] = 'UTF-32LE';
10961                 }
10962                 // UTF-16 Big Endian Without BOM
10963                 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10964                 {
10965                         if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10966                         {
10967                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10968                                 if ($parser->parse())
10969                                 {
10970                                         $encoding[] = $parser->encoding;
10971                                 }
10972                         }
10973                         $encoding[] = 'UTF-16BE';
10974                 }
10975                 // UTF-16 Little Endian Without BOM
10976                 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10977                 {
10978                         if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10979                         {
10980                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10981                                 if ($parser->parse())
10982                                 {
10983                                         $encoding[] = $parser->encoding;
10984                                 }
10985                         }
10986                         $encoding[] = 'UTF-16LE';
10987                 }
10988                 // US-ASCII (or superset)
10989                 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10990                 {
10991                         if ($pos = strpos($data, "\x3F\x3E"))
10992                         {
10993                                 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10994                                 if ($parser->parse())
10995                                 {
10996                                         $encoding[] = $parser->encoding;
10997                                 }
10998                         }
10999                         $encoding[] = 'UTF-8';
11000                 }
11001                 // Fallback to UTF-8
11002                 else
11003                 {
11004                         $encoding[] = 'UTF-8';
11005                 }
11006                 return $encoding;
11007         }
11008 }
11009
11010 /**
11011  * Decode HTML Entities
11012  *
11013  * This implements HTML5 as of revision 967 (2007-06-28)
11014  *
11015  * @package SimplePie
11016  */
11017 class SimplePie_Decode_HTML_Entities
11018 {
11019         /**
11020          * Data to be parsed
11021          *
11022          * @access private
11023          * @var string
11024          */
11025         var $data = '';
11026
11027         /**
11028          * Currently consumed bytes
11029          *
11030          * @access private
11031          * @var string
11032          */
11033         var $consumed = '';
11034
11035         /**
11036          * Position of the current byte being parsed
11037          *
11038          * @access private
11039          * @var int
11040          */
11041         var $position = 0;
11042
11043         /**
11044          * Create an instance of the class with the input data
11045          *
11046          * @access public
11047          * @param string $data Input data
11048          */
11049         function SimplePie_Decode_HTML_Entities($data)
11050         {
11051                 $this->data = $data;
11052         }
11053
11054         /**
11055          * Parse the input data
11056          *
11057          * @access public
11058          * @return string Output data
11059          */
11060         function parse()
11061         {
11062                 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11063                 {
11064                         $this->consume();
11065                         $this->entity();
11066                         $this->consumed = '';
11067                 }
11068                 return $this->data;
11069         }
11070
11071         /**
11072          * Consume the next byte
11073          *
11074          * @access private
11075          * @return mixed The next byte, or false, if there is no more data
11076          */
11077         function consume()
11078         {
11079                 if (isset($this->data[$this->position]))
11080                 {
11081                         $this->consumed .= $this->data[$this->position];
11082                         return $this->data[$this->position++];
11083                 }
11084                 else
11085                 {
11086                         $this->consumed = false;
11087                         return false;
11088                 }
11089         }
11090
11091         /**
11092          * Consume a range of characters
11093          *
11094          * @access private
11095          * @param string $chars Characters to consume
11096          * @return mixed A series of characters that match the range, or false
11097          */
11098         function consume_range($chars)
11099         {
11100                 if ($len = strspn($this->data, $chars, $this->position))
11101                 {
11102                         $data = substr($this->data, $this->position, $len);
11103                         $this->consumed .= $data;
11104                         $this->position += $len;
11105                         return $data;
11106                 }
11107                 else
11108                 {
11109                         $this->consumed = false;
11110                         return false;
11111                 }
11112         }
11113
11114         /**
11115          * Unconsume one byte
11116          *
11117          * @access private
11118          */
11119         function unconsume()
11120         {
11121                 $this->consumed = substr($this->consumed, 0, -1);
11122                 $this->position--;
11123         }
11124
11125         /**
11126          * Decode an entity
11127          *
11128          * @access private
11129          */
11130         function entity()
11131         {
11132                 switch ($this->consume())
11133                 {
11134                         case "\x09":
11135                         case "\x0A":
11136                         case "\x0B":
11137                         case "\x0B":
11138                         case "\x0C":
11139                         case "\x20":
11140                         case "\x3C":
11141                         case "\x26":
11142                         case false:
11143                                 break;
11144
11145                         case "\x23":
11146                                 switch ($this->consume())
11147                                 {
11148                                         case "\x78":
11149                                         case "\x58":
11150                                                 $range = '0123456789ABCDEFabcdef';
11151                                                 $hex = true;
11152                                                 break;
11153
11154                                         default:
11155                                                 $range = '0123456789';
11156                                                 $hex = false;
11157                                                 $this->unconsume();
11158                                                 break;
11159                                 }
11160
11161                                 if ($codepoint = $this->consume_range($range))
11162                                 {
11163                                         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");
11164
11165                                         if ($hex)
11166                                         {
11167                                                 $codepoint = hexdec($codepoint);
11168                                         }
11169                                         else
11170                                         {
11171                                                 $codepoint = intval($codepoint);
11172                                         }
11173
11174                                         if (isset($windows_1252_specials[$codepoint]))
11175                                         {
11176                                                 $replacement = $windows_1252_specials[$codepoint];
11177                                         }
11178                                         else
11179                                         {
11180                                                 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11181                                         }
11182
11183                                         if ($this->consume() != ';')
11184                                         {
11185                                                 $this->unconsume();
11186                                         }
11187
11188                                         $consumed_length = strlen($this->consumed);
11189                                         $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11190                                         $this->position += strlen($replacement) - $consumed_length;
11191                                 }
11192                                 break;
11193
11194                         default:
11195                                 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
11196
11197                                 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11198                                 {
11199                                         $consumed = substr($this->consumed, 1);
11200                                         if (isset($entities[$consumed]))
11201                                         {
11202                                                 $match = $consumed;
11203                                         }
11204                                 }
11205
11206                                 if ($match !== null)
11207                                 {
11208                                         $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11209                                         $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11210                                 }
11211                                 break;
11212                 }
11213         }
11214 }
11215
11216 /**
11217  * Date Parser
11218  *
11219  * @package SimplePie
11220  */
11221 class SimplePie_Parse_Date
11222 {
11223         /**
11224          * Input data
11225          *
11226          * @access protected
11227          * @var string
11228          */
11229         var $date;
11230
11231         /**
11232          * List of days, calendar day name => ordinal day number in the week
11233          *
11234          * @access protected
11235          * @var array
11236          */
11237         var $day = array(
11238                 // English
11239                 'mon' => 1,
11240                 'monday' => 1,
11241                 'tue' => 2,
11242                 'tuesday' => 2,
11243                 'wed' => 3,
11244                 'wednesday' => 3,
11245                 'thu' => 4,
11246                 'thursday' => 4,
11247                 'fri' => 5,
11248                 'friday' => 5,
11249                 'sat' => 6,
11250                 'saturday' => 6,
11251                 'sun' => 7,
11252                 'sunday' => 7,
11253                 // Dutch
11254                 'maandag' => 1,
11255                 'dinsdag' => 2,
11256                 'woensdag' => 3,
11257                 'donderdag' => 4,
11258                 'vrijdag' => 5,
11259                 'zaterdag' => 6,
11260                 'zondag' => 7,
11261                 // French
11262                 'lundi' => 1,
11263                 'mardi' => 2,
11264                 'mercredi' => 3,
11265                 'jeudi' => 4,
11266                 'vendredi' => 5,
11267                 'samedi' => 6,
11268                 'dimanche' => 7,
11269                 // German
11270                 'montag' => 1,
11271                 'dienstag' => 2,
11272                 'mittwoch' => 3,
11273                 'donnerstag' => 4,
11274                 'freitag' => 5,
11275                 'samstag' => 6,
11276                 'sonnabend' => 6,
11277                 'sonntag' => 7,
11278                 // Italian
11279                 'lunedì' => 1,
11280                 'martedì' => 2,
11281                 'mercoledì' => 3,
11282                 'giovedì' => 4,
11283                 'venerdì' => 5,
11284                 'sabato' => 6,
11285                 'domenica' => 7,
11286                 // Spanish
11287                 'lunes' => 1,
11288                 'martes' => 2,
11289                 'miércoles' => 3,
11290                 'jueves' => 4,
11291                 'viernes' => 5,
11292                 'sábado' => 6,
11293                 'domingo' => 7,
11294                 // Finnish
11295                 'maanantai' => 1,
11296                 'tiistai' => 2,
11297                 'keskiviikko' => 3,
11298                 'torstai' => 4,
11299                 'perjantai' => 5,
11300                 'lauantai' => 6,
11301                 'sunnuntai' => 7,
11302                 // Hungarian
11303                 'hétfő' => 1,
11304                 'kedd' => 2,
11305                 'szerda' => 3,
11306                 'csütörtok' => 4,
11307                 'péntek' => 5,
11308                 'szombat' => 6,
11309                 'vasárnap' => 7,
11310                 // Greek
11311                 'Δευ' => 1,
11312                 'Τρι' => 2,
11313                 'Τετ' => 3,
11314                 'Πεμ' => 4,
11315                 'Παρ' => 5,
11316                 'Σαβ' => 6,
11317                 'Κυρ' => 7,
11318         );
11319
11320         /**
11321          * List of months, calendar month name => calendar month number
11322          *
11323          * @access protected
11324          * @var array
11325          */
11326         var $month = array(
11327                 // English
11328                 'jan' => 1,
11329                 'january' => 1,
11330                 'feb' => 2,
11331                 'february' => 2,
11332                 'mar' => 3,
11333                 'march' => 3,
11334                 'apr' => 4,
11335                 'april' => 4,
11336                 'may' => 5,
11337                 // No long form of May
11338                 'jun' => 6,
11339                 'june' => 6,
11340                 'jul' => 7,
11341                 'july' => 7,
11342                 'aug' => 8,
11343                 'august' => 8,
11344                 'sep' => 9,
11345                 'september' => 8,
11346                 'oct' => 10,
11347                 'october' => 10,
11348                 'nov' => 11,
11349                 'november' => 11,
11350                 'dec' => 12,
11351                 'december' => 12,
11352                 // Dutch
11353                 'januari' => 1,
11354                 'februari' => 2,
11355                 'maart' => 3,
11356                 'april' => 4,
11357                 'mei' => 5,
11358                 'juni' => 6,
11359                 'juli' => 7,
11360                 'augustus' => 8,
11361                 'september' => 9,
11362                 'oktober' => 10,
11363                 'november' => 11,
11364                 'december' => 12,
11365                 // French
11366                 'janvier' => 1,
11367                 'février' => 2,
11368                 'mars' => 3,
11369                 'avril' => 4,
11370                 'mai' => 5,
11371                 'juin' => 6,
11372                 'juillet' => 7,
11373                 'août' => 8,
11374                 'septembre' => 9,
11375                 'octobre' => 10,
11376                 'novembre' => 11,
11377                 'décembre' => 12,
11378                 // German
11379                 'januar' => 1,
11380                 'februar' => 2,
11381                 'märz' => 3,
11382                 'april' => 4,
11383                 'mai' => 5,
11384                 'juni' => 6,
11385                 'juli' => 7,
11386                 'august' => 8,
11387                 'september' => 9,
11388                 'oktober' => 10,
11389                 'november' => 11,
11390                 'dezember' => 12,
11391                 // Italian
11392                 'gennaio' => 1,
11393                 'febbraio' => 2,
11394                 'marzo' => 3,
11395                 'aprile' => 4,
11396                 'maggio' => 5,
11397                 'giugno' => 6,
11398                 'luglio' => 7,
11399                 'agosto' => 8,
11400                 'settembre' => 9,
11401                 'ottobre' => 10,
11402                 'novembre' => 11,
11403                 'dicembre' => 12,
11404                 // Spanish
11405                 'enero' => 1,
11406                 'febrero' => 2,
11407                 'marzo' => 3,
11408                 'abril' => 4,
11409                 'mayo' => 5,
11410                 'junio' => 6,
11411                 'julio' => 7,
11412                 'agosto' => 8,
11413                 'septiembre' => 9,
11414                 'setiembre' => 9,
11415                 'octubre' => 10,
11416                 'noviembre' => 11,
11417                 'diciembre' => 12,
11418                 // Finnish
11419                 'tammikuu' => 1,
11420                 'helmikuu' => 2,
11421                 'maaliskuu' => 3,
11422                 'huhtikuu' => 4,
11423                 'toukokuu' => 5,
11424                 'kesäkuu' => 6,
11425                 'heinäkuu' => 7,
11426                 'elokuu' => 8,
11427                 'suuskuu' => 9,
11428                 'lokakuu' => 10,
11429                 'marras' => 11,
11430                 'joulukuu' => 12,
11431                 // Hungarian
11432                 'január' => 1,
11433                 'február' => 2,
11434                 'március' => 3,
11435                 'április' => 4,
11436                 'május' => 5,
11437                 'június' => 6,
11438                 'július' => 7,
11439                 'augusztus' => 8,
11440                 'szeptember' => 9,
11441                 'október' => 10,
11442                 'november' => 11,
11443                 'december' => 12,
11444                 // Greek
11445                 'Ιαν' => 1,
11446                 'Φεβ' => 2,
11447                 'Μάώ' => 3,
11448                 'Μαώ' => 3,
11449                 'Απρ' => 4,
11450                 'Μάι' => 5,
11451                 'Μαϊ' => 5,
11452                 'Μαι' => 5,
11453                 'Ιούν' => 6,
11454                 'Ιον' => 6,
11455                 'Ιούλ' => 7,
11456                 'Ιολ' => 7,
11457                 'Αύγ' => 8,
11458                 'Αυγ' => 8,
11459                 'Σεπ' => 9,
11460                 'Οκτ' => 10,
11461                 'Νοέ' => 11,
11462                 'Δεκ' => 12,
11463         );
11464
11465         /**
11466          * List of timezones, abbreviation => offset from UTC
11467          *
11468          * @access protected
11469          * @var array
11470          */
11471         var $timezone = array(
11472                 'ACDT' => 37800,
11473                 'ACIT' => 28800,
11474                 'ACST' => 34200,
11475                 'ACT' => -18000,
11476                 'ACWDT' => 35100,
11477                 'ACWST' => 31500,
11478                 'AEDT' => 39600,
11479                 'AEST' => 36000,
11480                 'AFT' => 16200,
11481                 'AKDT' => -28800,
11482                 'AKST' => -32400,
11483                 'AMDT' => 18000,
11484                 'AMT' => -14400,
11485                 'ANAST' => 46800,
11486                 'ANAT' => 43200,
11487                 'ART' => -10800,
11488                 'AZOST' => -3600,
11489                 'AZST' => 18000,
11490                 'AZT' => 14400,
11491                 'BIOT' => 21600,
11492                 'BIT' => -43200,
11493                 'BOT' => -14400,
11494                 'BRST' => -7200,
11495                 'BRT' => -10800,
11496                 'BST' => 3600,
11497                 'BTT' => 21600,
11498                 'CAST' => 18000,
11499                 'CAT' => 7200,
11500                 'CCT' => 23400,
11501                 'CDT' => -18000,
11502                 'CEDT' => 7200,
11503                 'CET' => 3600,
11504                 'CGST' => -7200,
11505                 'CGT' => -10800,
11506                 'CHADT' => 49500,
11507                 'CHAST' => 45900,
11508                 'CIST' => -28800,
11509                 'CKT' => -36000,
11510                 'CLDT' => -10800,
11511                 'CLST' => -14400,
11512                 'COT' => -18000,
11513                 'CST' => -21600,
11514                 'CVT' => -3600,
11515                 'CXT' => 25200,
11516                 'DAVT' => 25200,
11517                 'DTAT' => 36000,
11518                 'EADT' => -18000,
11519                 'EAST' => -21600,
11520                 'EAT' => 10800,
11521                 'ECT' => -18000,
11522                 'EDT' => -14400,
11523                 'EEST' => 10800,
11524                 'EET' => 7200,
11525                 'EGT' => -3600,
11526                 'EKST' => 21600,
11527                 'EST' => -18000,
11528                 'FJT' => 43200,
11529                 'FKDT' => -10800,
11530                 'FKST' => -14400,
11531                 'FNT' => -7200,
11532                 'GALT' => -21600,
11533                 'GEDT' => 14400,
11534                 'GEST' => 10800,
11535                 'GFT' => -10800,
11536                 'GILT' => 43200,
11537                 'GIT' => -32400,
11538                 'GST' => 14400,
11539                 'GST' => -7200,
11540                 'GYT' => -14400,
11541                 'HAA' => -10800,
11542                 'HAC' => -18000,
11543                 'HADT' => -32400,
11544                 'HAE' => -14400,
11545                 'HAP' => -25200,
11546                 'HAR' => -21600,
11547                 'HAST' => -36000,
11548                 'HAT' => -9000,
11549                 'HAY' => -28800,
11550                 'HKST' => 28800,
11551                 'HMT' => 18000,
11552                 'HNA' => -14400,
11553                 'HNC' => -21600,
11554                 'HNE' => -18000,
11555                 'HNP' => -28800,
11556                 'HNR' => -25200,
11557                 'HNT' => -12600,
11558                 'HNY' => -32400,
11559                 'IRDT' => 16200,
11560                 'IRKST' => 32400,
11561                 'IRKT' => 28800,
11562                 'IRST' => 12600,
11563                 'JFDT' => -10800,
11564                 'JFST' => -14400,
11565                 'JST' => 32400,
11566                 'KGST' => 21600,
11567                 'KGT' => 18000,
11568                 'KOST' => 39600,
11569                 'KOVST' => 28800,
11570                 'KOVT' => 25200,
11571                 'KRAST' => 28800,
11572                 'KRAT' => 25200,
11573                 'KST' => 32400,
11574                 'LHDT' => 39600,
11575                 'LHST' => 37800,
11576                 'LINT' => 50400,
11577                 'LKT' => 21600,
11578                 'MAGST' => 43200,
11579                 'MAGT' => 39600,
11580                 'MAWT' => 21600,
11581                 'MDT' => -21600,
11582                 'MESZ' => 7200,
11583                 'MEZ' => 3600,
11584                 'MHT' => 43200,
11585                 'MIT' => -34200,
11586                 'MNST' => 32400,
11587                 'MSDT' => 14400,
11588                 'MSST' => 10800,
11589                 'MST' => -25200,
11590                 'MUT' => 14400,
11591                 'MVT' => 18000,
11592                 'MYT' => 28800,
11593                 'NCT' => 39600,
11594                 'NDT' => -9000,
11595                 'NFT' => 41400,
11596                 'NMIT' => 36000,
11597                 'NOVST' => 25200,
11598                 'NOVT' => 21600,
11599                 'NPT' => 20700,
11600                 'NRT' => 43200,
11601                 'NST' => -12600,
11602                 'NUT' => -39600,
11603                 'NZDT' => 46800,
11604                 'NZST' => 43200,
11605                 'OMSST' => 25200,
11606                 'OMST' => 21600,
11607                 'PDT' => -25200,
11608                 'PET' => -18000,
11609                 'PETST' => 46800,
11610                 'PETT' => 43200,
11611                 'PGT' => 36000,
11612                 'PHOT' => 46800,
11613                 'PHT' => 28800,
11614                 'PKT' => 18000,
11615                 'PMDT' => -7200,
11616                 'PMST' => -10800,
11617                 'PONT' => 39600,
11618                 'PST' => -28800,
11619                 'PWT' => 32400,
11620                 'PYST' => -10800,
11621                 'PYT' => -14400,
11622                 'RET' => 14400,
11623                 'ROTT' => -10800,
11624                 'SAMST' => 18000,
11625                 'SAMT' => 14400,
11626                 'SAST' => 7200,
11627                 'SBT' => 39600,
11628                 'SCDT' => 46800,
11629                 'SCST' => 43200,
11630                 'SCT' => 14400,
11631                 'SEST' => 3600,
11632                 'SGT' => 28800,
11633                 'SIT' => 28800,
11634                 'SRT' => -10800,
11635                 'SST' => -39600,
11636                 'SYST' => 10800,
11637                 'SYT' => 7200,
11638                 'TFT' => 18000,
11639                 'THAT' => -36000,
11640                 'TJT' => 18000,
11641                 'TKT' => -36000,
11642                 'TMT' => 18000,
11643                 'TOT' => 46800,
11644                 'TPT' => 32400,
11645                 'TRUT' => 36000,
11646                 'TVT' => 43200,
11647                 'TWT' => 28800,
11648                 'UYST' => -7200,
11649                 'UYT' => -10800,
11650                 'UZT' => 18000,
11651                 'VET' => -14400,
11652                 'VLAST' => 39600,
11653                 'VLAT' => 36000,
11654                 'VOST' => 21600,
11655                 'VUT' => 39600,
11656                 'WAST' => 7200,
11657                 'WAT' => 3600,
11658                 'WDT' => 32400,
11659                 'WEST' => 3600,
11660                 'WFT' => 43200,
11661                 'WIB' => 25200,
11662                 'WIT' => 32400,
11663                 'WITA' => 28800,
11664                 'WKST' => 18000,
11665                 'WST' => 28800,
11666                 'YAKST' => 36000,
11667                 'YAKT' => 32400,
11668                 'YAPT' => 36000,
11669                 'YEKST' => 21600,
11670                 'YEKT' => 18000,
11671         );
11672
11673         /**
11674          * Cached PCRE for SimplePie_Parse_Date::$day
11675          *
11676          * @access protected
11677          * @var string
11678          */
11679         var $day_pcre;
11680
11681         /**
11682          * Cached PCRE for SimplePie_Parse_Date::$month
11683          *
11684          * @access protected
11685          * @var string
11686          */
11687         var $month_pcre;
11688
11689         /**
11690          * Array of user-added callback methods
11691          *
11692          * @access private
11693          * @var array
11694          */
11695         var $built_in = array();
11696
11697         /**
11698          * Array of user-added callback methods
11699          *
11700          * @access private
11701          * @var array
11702          */
11703         var $user = array();
11704
11705         /**
11706          * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11707          * self::month_pcre, and self::built_in
11708          *
11709          * @access private
11710          */
11711         function SimplePie_Parse_Date()
11712         {
11713                 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11714                 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11715
11716                 static $cache;
11717                 if (!isset($cache[get_class($this)]))
11718                 {
11719                         $all_methods = get_class_methods($this);
11720
11721                         foreach ($all_methods as $method)
11722                         {
11723                                 if (strtolower(substr($method, 0, 5)) === 'date_')
11724                                 {
11725                                         $cache[get_class($this)][] = $method;
11726                                 }
11727                         }
11728                 }
11729
11730                 foreach ($cache[get_class($this)] as $method)
11731                 {
11732                         $this->built_in[] = $method;
11733                 }
11734         }
11735
11736         /**
11737          * Get the object
11738          *
11739          * @access public
11740          */
11741         function get()
11742         {
11743                 static $object;
11744                 if (!$object)
11745                 {
11746                         $object =& new SimplePie_Parse_Date;
11747                 }
11748                 return $object;
11749         }
11750
11751         /**
11752          * Parse a date
11753          *
11754          * @final
11755          * @access public
11756          * @param string $date Date to parse
11757          * @return int Timestamp corresponding to date string, or false on failure
11758          */
11759         function parse($date)
11760         {
11761                 foreach ($this->user as $method)
11762                 {
11763                         if (($returned = call_user_func($method, $date)) !== false)
11764                         {
11765                                 return $returned;
11766                         }
11767                 }
11768
11769                 foreach ($this->built_in as $method)
11770                 {
11771                         if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11772                         {
11773                                 return $returned;
11774                         }
11775                 }
11776
11777                 return false;
11778         }
11779
11780         /**
11781          * Add a callback method to parse a date
11782          *
11783          * @final
11784          * @access public
11785          * @param callback $callback
11786          */
11787         function add_callback($callback)
11788         {
11789                 if (is_callable($callback))
11790                 {
11791                         $this->user[] = $callback;
11792                 }
11793                 else
11794                 {
11795                         trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11796                 }
11797         }
11798
11799         /**
11800          * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11801          * well as allowing any of upper or lower case "T", horizontal tabs, or
11802          * spaces to be used as the time seperator (including more than one))
11803          *
11804          * @access protected
11805          * @return int Timestamp
11806          */
11807         function date_w3cdtf($date)
11808         {
11809                 static $pcre;
11810                 if (!$pcre)
11811                 {
11812                         $year = '([0-9]{4})';
11813                         $month = $day = $hour = $minute = $second = '([0-9]{2})';
11814                         $decimal = '([0-9]*)';
11815                         $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11816                         $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11817                 }
11818                 if (preg_match($pcre, $date, $match))
11819                 {
11820                         /*
11821                         Capturing subpatterns:
11822                         1: Year
11823                         2: Month
11824                         3: Day
11825                         4: Hour
11826                         5: Minute
11827                         6: Second
11828                         7: Decimal fraction of a second
11829                         8: Zulu
11830                         9: Timezone ±
11831                         10: Timezone hours
11832                         11: Timezone minutes
11833                         */
11834
11835                         // Fill in empty matches
11836                         for ($i = count($match); $i <= 3; $i++)
11837                         {
11838                                 $match[$i] = '1';
11839                         }
11840
11841                         for ($i = count($match); $i <= 7; $i++)
11842                         {
11843                                 $match[$i] = '0';
11844                         }
11845
11846                         // Numeric timezone
11847                         if (isset($match[9]) && $match[9] !== '')
11848                         {
11849                                 $timezone = $match[10] * 3600;
11850                                 $timezone += $match[11] * 60;
11851                                 if ($match[9] === '-')
11852                                 {
11853                                         $timezone = 0 - $timezone;
11854                                 }
11855                         }
11856                         else
11857                         {
11858                                 $timezone = 0;
11859                         }
11860
11861                         // Convert the number of seconds to an integer, taking decimals into account
11862                         $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11863
11864                         return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11865                 }
11866                 else
11867                 {
11868                         return false;
11869                 }
11870         }
11871
11872         /**
11873          * Remove RFC822 comments
11874          *
11875          * @access protected
11876          * @param string $data Data to strip comments from
11877          * @return string Comment stripped string
11878          */
11879         function remove_rfc2822_comments($string)
11880         {
11881                 $string = (string) $string;
11882                 $position = 0;
11883                 $length = strlen($string);
11884                 $depth = 0;
11885
11886                 $output = '';
11887
11888                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11889                 {
11890                         $output .= substr($string, $position, $pos - $position);
11891                         $position = $pos + 1;
11892                         if ($string[$pos - 1] !== '\\')
11893                         {
11894                                 $depth++;
11895                                 while ($depth && $position < $length)
11896                                 {
11897                                         $position += strcspn($string, '()', $position);
11898                                         if ($string[$position - 1] === '\\')
11899                                         {
11900                                                 $position++;
11901                                                 continue;
11902                                         }
11903                                         elseif (isset($string[$position]))
11904                                         {
11905                                                 switch ($string[$position])
11906                                                 {
11907                                                         case '(':
11908                                                                 $depth++;
11909                                                                 break;
11910
11911                                                         case ')':
11912                                                                 $depth--;
11913                                                                 break;
11914                                                 }
11915                                                 $position++;
11916                                         }
11917                                         else
11918                                         {
11919                                                 break;
11920                                         }
11921                                 }
11922                         }
11923                         else
11924                         {
11925                                 $output .= '(';
11926                         }
11927                 }
11928                 $output .= substr($string, $position);
11929
11930                 return $output;
11931         }
11932
11933         /**
11934          * Parse RFC2822's date format
11935          *
11936          * @access protected
11937          * @return int Timestamp
11938          */
11939         function date_rfc2822($date)
11940         {
11941                 static $pcre;
11942                 if (!$pcre)
11943                 {
11944                         $wsp = '[\x09\x20]';
11945                         $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11946                         $optional_fws = $fws . '?';
11947                         $day_name = $this->day_pcre;
11948                         $month = $this->month_pcre;
11949                         $day = '([0-9]{1,2})';
11950                         $hour = $minute = $second = '([0-9]{2})';
11951                         $year = '([0-9]{2,4})';
11952                         $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11953                         $character_zone = '([A-Z]{1,5})';
11954                         $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11955                         $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';
11956                 }
11957                 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11958                 {
11959                         /*
11960                         Capturing subpatterns:
11961                         1: Day name
11962                         2: Day
11963                         3: Month
11964                         4: Year
11965                         5: Hour
11966                         6: Minute
11967                         7: Second
11968                         8: Timezone ±
11969                         9: Timezone hours
11970                         10: Timezone minutes
11971                         11: Alphabetic timezone
11972                         */
11973
11974                         // Find the month number
11975                         $month = $this->month[strtolower($match[3])];
11976
11977                         // Numeric timezone
11978                         if ($match[8] !== '')
11979                         {
11980                                 $timezone = $match[9] * 3600;
11981                                 $timezone += $match[10] * 60;
11982                                 if ($match[8] === '-')
11983                                 {
11984                                         $timezone = 0 - $timezone;
11985                                 }
11986                         }
11987                         // Character timezone
11988                         elseif (isset($this->timezone[strtoupper($match[11])]))
11989                         {
11990                                 $timezone = $this->timezone[strtoupper($match[11])];
11991                         }
11992                         // Assume everything else to be -0000
11993                         else
11994                         {
11995                                 $timezone = 0;
11996                         }
11997
11998                         // Deal with 2/3 digit years
11999                         if ($match[4] < 50)
12000                         {
12001                                 $match[4] += 2000;
12002                         }
12003                         elseif ($match[4] < 1000)
12004                         {
12005                                 $match[4] += 1900;
12006                         }
12007
12008                         // Second is optional, if it is empty set it to zero
12009                         if ($match[7] !== '')
12010                         {
12011                                 $second = $match[7];
12012                         }
12013                         else
12014                         {
12015                                 $second = 0;
12016                         }
12017
12018                         return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12019                 }
12020                 else
12021                 {
12022                         return false;
12023                 }
12024         }
12025
12026         /**
12027          * Parse RFC850's date format
12028          *
12029          * @access protected
12030          * @return int Timestamp
12031          */
12032         function date_rfc850($date)
12033         {
12034                 static $pcre;
12035                 if (!$pcre)
12036                 {
12037                         $space = '[\x09\x20]+';
12038                         $day_name = $this->day_pcre;
12039                         $month = $this->month_pcre;
12040                         $day = '([0-9]{1,2})';
12041                         $year = $hour = $minute = $second = '([0-9]{2})';
12042                         $zone = '([A-Z]{1,5})';
12043                         $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12044                 }
12045                 if (preg_match($pcre, $date, $match))
12046                 {
12047                         /*
12048                         Capturing subpatterns:
12049                         1: Day name
12050                         2: Day
12051                         3: Month
12052                         4: Year
12053                         5: Hour
12054                         6: Minute
12055                         7: Second
12056                         8: Timezone
12057                         */
12058
12059                         // Month
12060                         $month = $this->month[strtolower($match[3])];
12061
12062                         // Character timezone
12063                         if (isset($this->timezone[strtoupper($match[8])]))
12064                         {
12065                                 $timezone = $this->timezone[strtoupper($match[8])];
12066                         }
12067                         // Assume everything else to be -0000
12068                         else
12069                         {
12070                                 $timezone = 0;
12071                         }
12072
12073                         // Deal with 2 digit year
12074                         if ($match[4] < 50)
12075                         {
12076                                 $match[4] += 2000;
12077                         }
12078                         else
12079                         {
12080                                 $match[4] += 1900;
12081                         }
12082
12083                         return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12084                 }
12085                 else
12086                 {
12087                         return false;
12088                 }
12089         }
12090
12091         /**
12092          * Parse C99's asctime()'s date format
12093          *
12094          * @access protected
12095          * @return int Timestamp
12096          */
12097         function date_asctime($date)
12098         {
12099                 static $pcre;
12100                 if (!$pcre)
12101                 {
12102                         $space = '[\x09\x20]+';
12103                         $wday_name = $this->day_pcre;
12104                         $mon_name = $this->month_pcre;
12105                         $day = '([0-9]{1,2})';
12106                         $hour = $sec = $min = '([0-9]{2})';
12107                         $year = '([0-9]{4})';
12108                         $terminator = '\x0A?\x00?';
12109                         $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12110                 }
12111                 if (preg_match($pcre, $date, $match))
12112                 {
12113                         /*
12114                         Capturing subpatterns:
12115                         1: Day name
12116                         2: Month
12117                         3: Day
12118                         4: Hour
12119                         5: Minute
12120                         6: Second
12121                         7: Year
12122                         */
12123
12124                         $month = $this->month[strtolower($match[2])];
12125                         return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12126                 }
12127                 else
12128                 {
12129                         return false;
12130                 }
12131         }
12132
12133         /**
12134          * Parse dates using strtotime()
12135          *
12136          * @access protected
12137          * @return int Timestamp
12138          */
12139         function date_strtotime($date)
12140         {
12141                 $strtotime = strtotime($date);
12142                 if ($strtotime === -1 || $strtotime === false)
12143                 {
12144                         return false;
12145                 }
12146                 else
12147                 {
12148                         return $strtotime;
12149                 }
12150         }
12151 }
12152
12153 /**
12154  * Content-type sniffing
12155  *
12156  * @package SimplePie
12157  */
12158 class SimplePie_Content_Type_Sniffer
12159 {
12160         /**
12161          * File object
12162          *
12163          * @var SimplePie_File
12164          * @access private
12165          */
12166         var $file;
12167
12168         /**
12169          * Create an instance of the class with the input file
12170          *
12171          * @access public
12172          * @param SimplePie_Content_Type_Sniffer $file Input file
12173          */
12174         function SimplePie_Content_Type_Sniffer($file)
12175         {
12176                 $this->file = $file;
12177         }
12178
12179         /**
12180          * Get the Content-Type of the specified file
12181          *
12182          * @access public
12183          * @return string Actual Content-Type
12184          */
12185         function get_type()
12186         {
12187                 if (isset($this->file->headers['content-type']))
12188                 {
12189                         if (!isset($this->file->headers['content-encoding'])
12190                                 && ($this->file->headers['content-type'] === 'text/plain'
12191                                         || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12192                                         || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12193                         {
12194                                 return $this->text_or_binary();
12195                         }
12196
12197                         if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12198                         {
12199                                 $official = substr($this->file->headers['content-type'], 0, $pos);
12200                         }
12201                         else
12202                         {
12203                                 $official = $this->file->headers['content-type'];
12204                         }
12205                         $official = strtolower($official);
12206
12207                         if ($official === 'unknown/unknown'
12208                                 || $official === 'application/unknown')
12209                         {
12210                                 return $this->unknown();
12211                         }
12212                         elseif (substr($official, -4) === '+xml'
12213                                 || $official === 'text/xml'
12214                                 || $official === 'application/xml')
12215                         {
12216                                 return $official;
12217                         }
12218                         elseif (substr($official, 0, 6) === 'image/')
12219                         {
12220                                 if ($return = $this->image())
12221                                 {
12222                                         return $return;
12223                                 }
12224                                 else
12225                                 {
12226                                         return $official;
12227                                 }
12228                         }
12229                         elseif ($official === 'text/html')
12230                         {
12231                                 return $this->feed_or_html();
12232                         }
12233                         else
12234                         {
12235                                 return $official;
12236                         }
12237                 }
12238                 else
12239                 {
12240                         return $this->unknown();
12241                 }
12242         }
12243
12244         /**
12245          * Sniff text or binary
12246          *
12247          * @access private
12248          * @return string Actual Content-Type
12249          */
12250         function text_or_binary()
12251         {
12252                 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12253                         || substr($this->file->body, 0, 2) === "\xFF\xFE"
12254                         || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12255                         || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12256                 {
12257                         return 'text/plain';
12258                 }
12259                 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12260                 {
12261                         return 'application/octect-stream';
12262                 }
12263                 else
12264                 {
12265                         return 'text/plain';
12266                 }
12267         }
12268
12269         /**
12270          * Sniff unknown
12271          *
12272          * @access private
12273          * @return string Actual Content-Type
12274          */
12275         function unknown()
12276         {
12277                 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12278                 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12279                         || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12280                         || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12281                 {
12282                         return 'text/html';
12283                 }
12284                 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12285                 {
12286                         return 'application/pdf';
12287                 }
12288                 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12289                 {
12290                         return 'application/postscript';
12291                 }
12292                 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12293                         || substr($this->file->body, 0, 6) === 'GIF89a')
12294                 {
12295                         return 'image/gif';
12296                 }
12297                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12298                 {
12299                         return 'image/png';
12300                 }
12301                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12302                 {
12303                         return 'image/jpeg';
12304                 }
12305                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12306                 {
12307                         return 'image/bmp';
12308                 }
12309                 else
12310                 {
12311                         return $this->text_or_binary();
12312                 }
12313         }
12314
12315         /**
12316          * Sniff images
12317          *
12318          * @access private
12319          * @return string Actual Content-Type
12320          */
12321         function image()
12322         {
12323                 if (substr($this->file->body, 0, 6) === 'GIF87a'
12324                         || substr($this->file->body, 0, 6) === 'GIF89a')
12325                 {
12326                         return 'image/gif';
12327                 }
12328                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12329                 {
12330                         return 'image/png';
12331                 }
12332                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12333                 {
12334                         return 'image/jpeg';
12335                 }
12336                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12337                 {
12338                         return 'image/bmp';
12339                 }
12340                 else
12341                 {
12342                         return false;
12343                 }
12344         }
12345
12346         /**
12347          * Sniff HTML
12348          *
12349          * @access private
12350          * @return string Actual Content-Type
12351          */
12352         function feed_or_html()
12353         {
12354                 $len = strlen($this->file->body);
12355                 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12356
12357                 while ($pos < $len)
12358                 {
12359                         switch ($this->file->body[$pos])
12360                         {
12361                                 case "\x09":
12362                                 case "\x0A":
12363                                 case "\x0D":
12364                                 case "\x20":
12365                                         $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12366                                         continue 2;
12367
12368                                 case '<':
12369                                         $pos++;
12370                                         break;
12371
12372                                 default:
12373                                         return 'text/html';
12374                         }
12375
12376                         if (substr($this->file->body, $pos, 3) === '!--')
12377                         {
12378                                 $pos += 3;
12379                                 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12380                                 {
12381                                         $pos += 3;
12382                                 }
12383                                 else
12384                                 {
12385                                         return 'text/html';
12386                                 }
12387                         }
12388                         elseif (substr($this->file->body, $pos, 1) === '!')
12389                         {
12390                                 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12391                                 {
12392                                         $pos++;
12393                                 }
12394                                 else
12395                                 {
12396                                         return 'text/html';
12397                                 }
12398                         }
12399                         elseif (substr($this->file->body, $pos, 1) === '?')
12400                         {
12401                                 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12402                                 {
12403                                         $pos += 2;
12404                                 }
12405                                 else
12406                                 {
12407                                         return 'text/html';
12408                                 }
12409                         }
12410                         elseif (substr($this->file->body, $pos, 3) === 'rss'
12411                                 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12412                         {
12413                                 return 'application/rss+xml';
12414                         }
12415                         elseif (substr($this->file->body, $pos, 4) === 'feed')
12416                         {
12417                                 return 'application/atom+xml';
12418                         }
12419                         else
12420                         {
12421                                 return 'text/html';
12422                         }
12423                 }
12424
12425                 return 'text/html';
12426         }
12427 }
12428
12429 /**
12430  * Parses the XML Declaration
12431  *
12432  * @package SimplePie
12433  */
12434 class SimplePie_XML_Declaration_Parser
12435 {
12436         /**
12437          * XML Version
12438          *
12439          * @access public
12440          * @var string
12441          */
12442         var $version = '1.0';
12443
12444         /**
12445          * Encoding
12446          *
12447          * @access public
12448          * @var string
12449          */
12450         var $encoding = 'UTF-8';
12451
12452         /**
12453          * Standalone
12454          *
12455          * @access public
12456          * @var bool
12457          */
12458         var $standalone = false;
12459
12460         /**
12461          * Current state of the state machine
12462          *
12463          * @access private
12464          * @var string
12465          */
12466         var $state = 'before_version_name';
12467
12468         /**
12469          * Input data
12470          *
12471          * @access private
12472          * @var string
12473          */
12474         var $data = '';
12475
12476         /**
12477          * Input data length (to avoid calling strlen() everytime this is needed)
12478          *
12479          * @access private
12480          * @var int
12481          */
12482         var $data_length = 0;
12483
12484         /**
12485          * Current position of the pointer
12486          *
12487          * @var int
12488          * @access private
12489          */
12490         var $position = 0;
12491
12492         /**
12493          * Create an instance of the class with the input data
12494          *
12495          * @access public
12496          * @param string $data Input data
12497          */
12498         function SimplePie_XML_Declaration_Parser($data)
12499         {
12500                 $this->data = $data;
12501                 $this->data_length = strlen($this->data);
12502         }
12503
12504         /**
12505          * Parse the input data
12506          *
12507          * @access public
12508          * @return bool true on success, false on failure
12509          */
12510         function parse()
12511         {
12512                 while ($this->state && $this->state !== 'emit' && $this->has_data())
12513                 {
12514                         $state = $this->state;
12515                         $this->$state();
12516                 }
12517                 $this->data = '';
12518                 if ($this->state === 'emit')
12519                 {
12520                         return true;
12521                 }
12522                 else
12523                 {
12524                         $this->version = '';
12525                         $this->encoding = '';
12526                         $this->standalone = '';
12527                         return false;
12528                 }
12529         }
12530
12531         /**
12532          * Check whether there is data beyond the pointer
12533          *
12534          * @access private
12535          * @return bool true if there is further data, false if not
12536          */
12537         function has_data()
12538         {
12539                 return (bool) ($this->position < $this->data_length);
12540         }
12541
12542         /**
12543          * Advance past any whitespace
12544          *
12545          * @return int Number of whitespace characters passed
12546          */
12547         function skip_whitespace()
12548         {
12549                 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12550                 $this->position += $whitespace;
12551                 return $whitespace;
12552         }
12553
12554         /**
12555          * Read value
12556          */
12557         function get_value()
12558         {
12559                 $quote = substr($this->data, $this->position, 1);
12560                 if ($quote === '"' || $quote === "'")
12561                 {
12562                         $this->position++;
12563                         $len = strcspn($this->data, $quote, $this->position);
12564                         if ($this->has_data())
12565                         {
12566                                 $value = substr($this->data, $this->position, $len);
12567                                 $this->position += $len + 1;
12568                                 return $value;
12569                         }
12570                 }
12571                 return false;
12572         }
12573
12574         function before_version_name()
12575         {
12576                 if ($this->skip_whitespace())
12577                 {
12578                         $this->state = 'version_name';
12579                 }
12580                 else
12581                 {
12582                         $this->state = false;
12583                 }
12584         }
12585
12586         function version_name()
12587         {
12588                 if (substr($this->data, $this->position, 7) === 'version')
12589                 {
12590                         $this->position += 7;
12591                         $this->skip_whitespace();
12592                         $this->state = 'version_equals';
12593                 }
12594                 else
12595                 {
12596                         $this->state = false;
12597                 }
12598         }
12599
12600         function version_equals()
12601         {
12602                 if (substr($this->data, $this->position, 1) === '=')
12603                 {
12604                         $this->position++;
12605                         $this->skip_whitespace();
12606                         $this->state = 'version_value';
12607                 }
12608                 else
12609                 {
12610                         $this->state = false;
12611                 }
12612         }
12613
12614         function version_value()
12615         {
12616                 if ($this->version = $this->get_value())
12617                 {
12618                         $this->skip_whitespace();
12619                         if ($this->has_data())
12620                         {
12621                                 $this->state = 'encoding_name';
12622                         }
12623                         else
12624                         {
12625                                 $this->state = 'emit';
12626                         }
12627                 }
12628                 else
12629                 {
12630                         $this->state = 'standalone_name';
12631                 }
12632         }
12633
12634         function encoding_name()
12635         {
12636                 if (substr($this->data, $this->position, 8) === 'encoding')
12637                 {
12638                         $this->position += 8;
12639                         $this->skip_whitespace();
12640                         $this->state = 'encoding_equals';
12641                 }
12642                 else
12643                 {
12644                         $this->state = false;
12645                 }
12646         }
12647
12648         function encoding_equals()
12649         {
12650                 if (substr($this->data, $this->position, 1) === '=')
12651                 {
12652                         $this->position++;
12653                         $this->skip_whitespace();
12654                         $this->state = 'encoding_value';
12655                 }
12656                 else
12657                 {
12658                         $this->state = false;
12659                 }
12660         }
12661
12662         function encoding_value()
12663         {
12664                 if ($this->encoding = $this->get_value())
12665                 {
12666                         $this->skip_whitespace();
12667                         if ($this->has_data())
12668                         {
12669                                 $this->state = 'standalone_name';
12670                         }
12671                         else
12672                         {
12673                                 $this->state = 'emit';
12674                         }
12675                 }
12676                 else
12677                 {
12678                         $this->state = false;
12679                 }
12680         }
12681
12682         function standalone_name()
12683         {
12684                 if (substr($this->data, $this->position, 10) === 'standalone')
12685                 {
12686                         $this->position += 10;
12687                         $this->skip_whitespace();
12688                         $this->state = 'standalone_equals';
12689                 }
12690                 else
12691                 {
12692                         $this->state = false;
12693                 }
12694         }
12695
12696         function standalone_equals()
12697         {
12698                 if (substr($this->data, $this->position, 1) === '=')
12699                 {
12700                         $this->position++;
12701                         $this->skip_whitespace();
12702                         $this->state = 'standalone_value';
12703                 }
12704                 else
12705                 {
12706                         $this->state = false;
12707                 }
12708         }
12709
12710         function standalone_value()
12711         {
12712                 if ($standalone = $this->get_value())
12713                 {
12714                         switch ($standalone)
12715                         {
12716                                 case 'yes':
12717                                         $this->standalone = true;
12718                                         break;
12719
12720                                 case 'no':
12721                                         $this->standalone = false;
12722                                         break;
12723
12724                                 default:
12725                                         $this->state = false;
12726                                         return;
12727                         }
12728
12729                         $this->skip_whitespace();
12730                         if ($this->has_data())
12731                         {
12732                                 $this->state = false;
12733                         }
12734                         else
12735                         {
12736                                 $this->state = 'emit';
12737                         }
12738                 }
12739                 else
12740                 {
12741                         $this->state = false;
12742                 }
12743         }
12744 }
12745
12746 class SimplePie_Locator
12747 {
12748         var $useragent;
12749         var $timeout;
12750         var $file;
12751         var $local = array();
12752         var $elsewhere = array();
12753         var $file_class = 'SimplePie_File';
12754         var $cached_entities = array();
12755         var $http_base;
12756         var $base;
12757         var $base_location = 0;
12758         var $checked_feeds = 0;
12759         var $max_checked_feeds = 10;
12760         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12761
12762         function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12763         {
12764                 $this->file =& $file;
12765                 $this->file_class = $file_class;
12766                 $this->useragent = $useragent;
12767                 $this->timeout = $timeout;
12768                 $this->max_checked_feeds = $max_checked_feeds;
12769                 $this->content_type_sniffer_class = $content_type_sniffer_class;
12770         }
12771
12772         function find($type = SIMPLEPIE_LOCATOR_ALL)
12773         {
12774                 if ($this->is_feed($this->file))
12775                 {
12776                         return $this->file;
12777                 }
12778
12779                 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12780                 {
12781                         $sniffer =& new $this->content_type_sniffer_class($this->file);
12782                         if ($sniffer->get_type() !== 'text/html')
12783                         {
12784                                 return null;
12785                         }
12786                 }
12787
12788                 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12789                 {
12790                         $this->get_base();
12791                 }
12792
12793                 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12794                 {
12795                         return $working;
12796                 }
12797
12798                 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12799                 {
12800                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12801                         {
12802                                 return $working;
12803                         }
12804
12805                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12806                         {
12807                                 return $working;
12808                         }
12809
12810                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12811                         {
12812                                 return $working;
12813                         }
12814
12815                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12816                         {
12817                                 return $working;
12818                         }
12819                 }
12820                 return null;
12821         }
12822
12823         function is_feed(&$file)
12824         {
12825                 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12826                 {
12827                         $sniffer =& new $this->content_type_sniffer_class($file);
12828                         $sniffed = $sniffer->get_type();
12829                         if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12830                         {
12831                                 return true;
12832                         }
12833                         else
12834                         {
12835                                 return false;
12836                         }
12837                 }
12838                 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12839                 {
12840                         return true;
12841                 }
12842                 else
12843                 {
12844                         return false;
12845                 }
12846         }
12847
12848         function get_base()
12849         {
12850                 $this->http_base = $this->file->url;
12851                 $this->base = $this->http_base;
12852                 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12853                 foreach ($elements as $element)
12854                 {
12855                         if ($element['attribs']['href']['data'] !== '')
12856                         {
12857                                 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12858                                 $this->base_location = $element['offset'];
12859                                 break;
12860                         }
12861                 }
12862         }
12863
12864         function autodiscovery()
12865         {
12866                 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
12867                 $done = array();
12868                 foreach ($links as $link)
12869                 {
12870                         if ($this->checked_feeds == $this->max_checked_feeds)
12871                         {
12872                                 break;
12873                         }
12874                         if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12875                         {
12876                                 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12877
12878                                 if ($this->base_location < $link['offset'])
12879                                 {
12880                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12881                                 }
12882                                 else
12883                                 {
12884                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12885                                 }
12886
12887                                 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))))
12888                                 {
12889                                         $this->checked_feeds++;
12890                                         $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12891                                         if ($this->is_feed($feed))
12892                                         {
12893                                                 return $feed;
12894                                         }
12895                                 }
12896                                 $done[] = $href;
12897                         }
12898                 }
12899                 return null;
12900         }
12901
12902         function get_links()
12903         {
12904                 $links = SimplePie_Misc::get_element('a', $this->file->body);
12905                 foreach ($links as $link)
12906                 {
12907                         if (isset($link['attribs']['href']['data']))
12908                         {
12909                                 $href = trim($link['attribs']['href']['data']);
12910                                 $parsed = SimplePie_Misc::parse_url($href);
12911                                 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12912                                 {
12913                                         if ($this->base_location < $link['offset'])
12914                                         {
12915                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12916                                         }
12917                                         else
12918                                         {
12919                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12920                                         }
12921
12922                                         $current = SimplePie_Misc::parse_url($this->file->url);
12923
12924                                         if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12925                                         {
12926                                                 $this->local[] = $href;
12927                                         }
12928                                         else
12929                                         {
12930                                                 $this->elsewhere[] = $href;
12931                                         }
12932                                 }
12933                         }
12934                 }
12935                 $this->local = array_unique($this->local);
12936                 $this->elsewhere = array_unique($this->elsewhere);
12937                 if (!empty($this->local) || !empty($this->elsewhere))
12938                 {
12939                         return true;
12940                 }
12941                 return null;
12942         }
12943
12944         function extension(&$array)
12945         {
12946                 foreach ($array as $key => $value)
12947                 {
12948                         if ($this->checked_feeds == $this->max_checked_feeds)
12949                         {
12950                                 break;
12951                         }
12952                         if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12953                         {
12954                                 $this->checked_feeds++;
12955                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12956                                 if ($this->is_feed($feed))
12957                                 {
12958                                         return $feed;
12959                                 }
12960                                 else
12961                                 {
12962                                         unset($array[$key]);
12963                                 }
12964                         }
12965                 }
12966                 return null;
12967         }
12968
12969         function body(&$array)
12970         {
12971                 foreach ($array as $key => $value)
12972                 {
12973                         if ($this->checked_feeds == $this->max_checked_feeds)
12974                         {
12975                                 break;
12976                         }
12977                         if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12978                         {
12979                                 $this->checked_feeds++;
12980                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12981                                 if ($this->is_feed($feed))
12982                                 {
12983                                         return $feed;
12984                                 }
12985                                 else
12986                                 {
12987                                         unset($array[$key]);
12988                                 }
12989                         }
12990                 }
12991                 return null;
12992         }
12993 }
12994
12995 class SimplePie_Parser
12996 {
12997         var $error_code;
12998         var $error_string;
12999         var $current_line;
13000         var $current_column;
13001         var $current_byte;
13002         var $separator = ' ';
13003         var $feed = false;
13004         var $namespace = array('');
13005         var $element = array('');
13006         var $xml_base = array('');
13007         var $xml_base_explicit = array(false);
13008         var $xml_lang = array('');
13009         var $data = array();
13010         var $datas = array(array());
13011         var $current_xhtml_construct = -1;
13012         var $encoding;
13013
13014         function parse(&$data, $encoding)
13015         {
13016                 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13017                 if (strtoupper($encoding) == 'US-ASCII')
13018                 {
13019                         $this->encoding = 'UTF-8';
13020                 }
13021                 else
13022                 {
13023                         $this->encoding = $encoding;
13024                 }
13025
13026                 // Strip BOM:
13027                 // UTF-32 Big Endian BOM
13028                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13029                 {
13030                         $data = substr($data, 4);
13031                 }
13032                 // UTF-32 Little Endian BOM
13033                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13034                 {
13035                         $data = substr($data, 4);
13036                 }
13037                 // UTF-16 Big Endian BOM
13038                 elseif (substr($data, 0, 2) === "\xFE\xFF")
13039                 {
13040                         $data = substr($data, 2);
13041                 }
13042                 // UTF-16 Little Endian BOM
13043                 elseif (substr($data, 0, 2) === "\xFF\xFE")
13044                 {
13045                         $data = substr($data, 2);
13046                 }
13047                 // UTF-8 BOM
13048                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13049                 {
13050                         $data = substr($data, 3);
13051                 }
13052
13053                 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13054                 {
13055                         $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13056                         if ($declaration->parse())
13057                         {
13058                                 $data = substr($data, $pos + 2);
13059                                 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13060                         }
13061                         else
13062                         {
13063                                 $this->error_string = 'SimplePie bug! Please report this!';
13064                                 return false;
13065                         }
13066                 }
13067
13068                 // Work around libxml bug
13069                 $data = str_replace('&lt;', '&#60;', $data);
13070                 $data = str_replace('&gt;', '&#62;', $data);
13071                 $data = str_replace('&amp;', '&#38;', $data);
13072                 $data = str_replace('&apos;', '&#39;', $data);
13073                 $data = str_replace('&quot;', '&#34;', $data);
13074
13075                 $return = true;
13076
13077                 // Create the parser
13078                 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13079                 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13080                 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13081                 xml_set_object($xml, $this);
13082                 xml_set_character_data_handler($xml, 'cdata');
13083                 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13084
13085                 // Parse!
13086                 if (!xml_parse($xml, $data, true))
13087                 {
13088                         $this->error_code = xml_get_error_code($xml);
13089                         $this->error_string = xml_error_string($this->error_code);
13090                         $return = false;
13091                 }
13092                 $this->current_line = xml_get_current_line_number($xml);
13093                 $this->current_column = xml_get_current_column_number($xml);
13094                 $this->current_byte = xml_get_current_byte_index($xml);
13095                 xml_parser_free($xml);
13096                 return $return;
13097         }
13098
13099         function get_error_code()
13100         {
13101                 return $this->error_code;
13102         }
13103
13104         function get_error_string()
13105         {
13106                 return $this->error_string;
13107         }
13108
13109         function get_current_line()
13110         {
13111                 return $this->current_line;
13112         }
13113
13114         function get_current_column()
13115         {
13116                 return $this->current_column;
13117         }
13118
13119         function get_current_byte()
13120         {
13121                 return $this->current_byte;
13122         }
13123
13124         function get_data()
13125         {
13126                 return $this->data;
13127         }
13128
13129         function tag_open($parser, $tag, $attributes)
13130         {
13131                 if ($this->feed === 0)
13132                 {
13133                         return;
13134                 }
13135                 elseif ($this->feed == false)
13136                 {
13137                         if (in_array($tag, array(
13138                                 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13139                                 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13140                                 'rss',
13141                                 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13142                         )))
13143                         {
13144                                         $this->feed = 1;
13145                         }
13146                 }
13147                 else
13148                 {
13149                         $this->feed++;
13150                 }
13151
13152                 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13153
13154                 $attribs = array();
13155                 foreach ($attributes as $name => $value)
13156                 {
13157                         list($attrib_namespace, $attribute) = $this->split_ns($name);
13158                         $attribs[$attrib_namespace][$attribute] = $value;
13159                 }
13160
13161                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13162                 {
13163                         $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13164                         $this->xml_base_explicit[] = true;
13165                 }
13166                 else
13167                 {
13168                         $this->xml_base[] = end($this->xml_base);
13169                         $this->xml_base_explicit[] = end($this->xml_base_explicit);
13170                 }
13171
13172                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13173                 {
13174                         $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13175                 }
13176                 else
13177                 {
13178                         $this->xml_lang[] = end($this->xml_lang);
13179                 }
13180
13181                 if ($this->current_xhtml_construct >= 0)
13182                 {
13183                         $this->current_xhtml_construct++;
13184                         if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13185                         {
13186                                 $this->data['data'] .= '<' . end($this->element);
13187                                 if (isset($attribs['']))
13188                                 {
13189                                         foreach ($attribs[''] as $name => $value)
13190                                         {
13191                                                 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13192                                         }
13193                                 }
13194                                 $this->data['data'] .= '>';
13195                         }
13196                 }
13197                 else
13198                 {
13199                         $this->datas[] =& $this->data;
13200                         $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13201                         $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));
13202                         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')
13203                         || (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'))
13204                         {
13205                                 $this->current_xhtml_construct = 0;
13206                         }
13207                 }
13208         }
13209
13210         function cdata($parser, $cdata)
13211         {
13212                 if ($this->current_xhtml_construct >= 0)
13213                 {
13214                         $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13215                 }
13216                 elseif ($this->feed > 1)
13217                 {
13218                         $this->data['data'] .= $cdata;
13219                 }
13220         }
13221
13222         function tag_close($parser, $tag)
13223         {
13224                 if (!$this->feed)
13225                 {
13226                         return;
13227                 }
13228
13229                 if ($this->current_xhtml_construct >= 0)
13230                 {
13231                         $this->current_xhtml_construct--;
13232                         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')))
13233                         {
13234                                 $this->data['data'] .= '</' . end($this->element) . '>';
13235                         }
13236                 }
13237                 if ($this->current_xhtml_construct == -1)
13238                 {
13239                         $this->data =& $this->datas[$this->feed];
13240                         array_pop($this->datas);
13241                 }
13242
13243                 array_pop($this->element);
13244                 array_pop($this->namespace);
13245                 array_pop($this->xml_base);
13246                 array_pop($this->xml_base_explicit);
13247                 array_pop($this->xml_lang);
13248                 $this->feed--;
13249         }
13250
13251         function split_ns($string)
13252         {
13253                 static $cache = array();
13254                 if (!isset($cache[$string]))
13255                 {
13256                         if ($pos = strpos($string, $this->separator))
13257                         {
13258                                 static $separator_length;
13259                                 if (!$separator_length)
13260                                 {
13261                                         $separator_length = strlen($this->separator);
13262                                 }
13263                                 $namespace = substr($string, 0, $pos);
13264                                 $local_name = substr($string, $pos + $separator_length);
13265                                 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13266                                 {
13267                                         $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13268                                 }
13269
13270                                 // Normalize the Media RSS namespaces
13271                                 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13272                                 {
13273                                         $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13274                                 }
13275                                 $cache[$string] = array($namespace, $local_name);
13276                         }
13277                         else
13278                         {
13279                                 $cache[$string] = array('', $string);
13280                         }
13281                 }
13282                 return $cache[$string];
13283         }
13284 }
13285
13286 /**
13287  * @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
13288  */
13289 class SimplePie_Sanitize
13290 {
13291         // Private vars
13292         var $base;
13293
13294         // Options
13295         var $remove_div = true;
13296         var $image_handler = '';
13297         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13298         var $encode_instead_of_strip = false;
13299         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13300         var $strip_comments = false;
13301         var $output_encoding = 'UTF-8';
13302         var $enable_cache = true;
13303         var $cache_location = './cache';
13304         var $cache_name_function = 'md5';
13305         var $cache_class = 'SimplePie_Cache';
13306         var $file_class = 'SimplePie_File';
13307         var $timeout = 10;
13308         var $useragent = '';
13309         var $force_fsockopen = false;
13310
13311         var $replace_url_attributes = array(
13312                 'a' => 'href',
13313                 'area' => 'href',
13314                 'blockquote' => 'cite',
13315                 'del' => 'cite',
13316                 'form' => 'action',
13317                 'img' => array('longdesc', 'src'),
13318                 'input' => 'src',
13319                 'ins' => 'cite',
13320                 'q' => 'cite'
13321         );
13322
13323         function remove_div($enable = true)
13324         {
13325                 $this->remove_div = (bool) $enable;
13326         }
13327
13328         function set_image_handler($page = false)
13329         {
13330                 if ($page)
13331                 {
13332                         $this->image_handler = (string) $page;
13333                 }
13334                 else
13335                 {
13336                         $this->image_handler = false;
13337                 }
13338         }
13339
13340         function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13341         {
13342                 if (isset($enable_cache))
13343                 {
13344                         $this->enable_cache = (bool) $enable_cache;
13345                 }
13346
13347                 if ($cache_location)
13348                 {
13349                         $this->cache_location = (string) $cache_location;
13350                 }
13351
13352                 if ($cache_name_function)
13353                 {
13354                         $this->cache_name_function = (string) $cache_name_function;
13355                 }
13356
13357                 if ($cache_class)
13358                 {
13359                         $this->cache_class = (string) $cache_class;
13360                 }
13361         }
13362
13363         function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13364         {
13365                 if ($file_class)
13366                 {
13367                         $this->file_class = (string) $file_class;
13368                 }
13369
13370                 if ($timeout)
13371                 {
13372                         $this->timeout = (string) $timeout;
13373                 }
13374
13375                 if ($useragent)
13376                 {
13377                         $this->useragent = (string) $useragent;
13378                 }
13379
13380                 if ($force_fsockopen)
13381                 {
13382                         $this->force_fsockopen = (string) $force_fsockopen;
13383                 }
13384         }
13385
13386         function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13387         {
13388                 if ($tags)
13389                 {
13390                         if (is_array($tags))
13391                         {
13392                                 $this->strip_htmltags = $tags;
13393                         }
13394                         else
13395                         {
13396                                 $this->strip_htmltags = explode(',', $tags);
13397                         }
13398                 }
13399                 else
13400                 {
13401                         $this->strip_htmltags = false;
13402                 }
13403         }
13404
13405         function encode_instead_of_strip($encode = false)
13406         {
13407                 $this->encode_instead_of_strip = (bool) $encode;
13408         }
13409
13410         function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13411         {
13412                 if ($attribs)
13413                 {
13414                         if (is_array($attribs))
13415                         {
13416                                 $this->strip_attributes = $attribs;
13417                         }
13418                         else
13419                         {
13420                                 $this->strip_attributes = explode(',', $attribs);
13421                         }
13422                 }
13423                 else
13424                 {
13425                         $this->strip_attributes = false;
13426                 }
13427         }
13428
13429         function strip_comments($strip = false)
13430         {
13431                 $this->strip_comments = (bool) $strip;
13432         }
13433
13434         function set_output_encoding($encoding = 'UTF-8')
13435         {
13436                 $this->output_encoding = (string) $encoding;
13437         }
13438
13439         /**
13440          * Set element/attribute key/value pairs of HTML attributes
13441          * containing URLs that need to be resolved relative to the feed
13442          *
13443          * @access public
13444          * @since 1.0
13445          * @param array $element_attribute Element/attribute key/value pairs
13446          */
13447         function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
13448         {
13449                 $this->replace_url_attributes = (array) $element_attribute;
13450         }
13451
13452         function sanitize($data, $type, $base = '')
13453         {
13454                 $data = trim($data);
13455                 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13456                 {
13457                         if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13458                         {
13459                                 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))
13460                                 {
13461                                         $type |= SIMPLEPIE_CONSTRUCT_HTML;
13462                                 }
13463                                 else
13464                                 {
13465                                         $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13466                                 }
13467                         }
13468
13469                         if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13470                         {
13471                                 $data = base64_decode($data);
13472                         }
13473
13474                         if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13475                         {
13476                                 if ($this->remove_div)
13477                                 {
13478                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13479                                         $data = preg_replace('/<\/div>$/', '', $data);
13480                                 }
13481                                 else
13482                                 {
13483                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13484                                 }
13485                         }
13486
13487                         if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13488                         {
13489                                 // Strip comments
13490                                 if ($this->strip_comments)
13491                                 {
13492                                         $data = SimplePie_Misc::strip_comments($data);
13493                                 }
13494
13495                                 // Strip out HTML tags and attributes that might cause various security problems.
13496                                 // Based on recommendations by Mark Pilgrim at:
13497                                 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13498                                 if ($this->strip_htmltags)
13499                                 {
13500                                         foreach ($this->strip_htmltags as $tag)
13501                                         {
13502                                                 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13503                                                 while (preg_match($pcre, $data))
13504                                                 {
13505                                                         $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13506                                                 }
13507                                         }
13508                                 }
13509
13510                                 if ($this->strip_attributes)
13511                                 {
13512                                         foreach ($this->strip_attributes as $attrib)
13513                                         {
13514                                                 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
13515                                         }
13516                                 }
13517
13518                                 // Replace relative URLs
13519                                 $this->base = $base;
13520                                 foreach ($this->replace_url_attributes as $element => $attributes)
13521                                 {
13522                                         $data = $this->replace_urls($data, $element, $attributes);
13523                                 }
13524
13525                                 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13526                                 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13527                                 {
13528                                         $images = SimplePie_Misc::get_element('img', $data);
13529                                         foreach ($images as $img)
13530                                         {
13531                                                 if (isset($img['attribs']['src']['data']))
13532                                                 {
13533                                                         $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13534                                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13535
13536                                                         if ($cache->load())
13537                                                         {
13538                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13539                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13540                                                         }
13541                                                         else
13542                                                         {
13543                                                                 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13544                                                                 $headers = $file->headers;
13545
13546                                                                 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13547                                                                 {
13548                                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13549                                                                         {
13550                                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13551                                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13552                                                                         }
13553                                                                         else
13554                                                                         {
13555                                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13556                                                                         }
13557                                                                 }
13558                                                         }
13559                                                 }
13560                                         }
13561                                 }
13562
13563                                 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13564                                 $data = trim($data);
13565                         }
13566
13567                         if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13568                         {
13569                                 $data = SimplePie_Misc::absolutize_url($data, $base);
13570                         }
13571
13572                         if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13573                         {
13574                                 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13575                         }
13576
13577                         if ($this->output_encoding != 'UTF-8')
13578                         {
13579                                 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13580                         }
13581                 }
13582                 return $data;
13583         }
13584
13585         function replace_urls($data, $tag, $attributes)
13586         {
13587                 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13588                 {
13589                         $elements = SimplePie_Misc::get_element($tag, $data);
13590                         foreach ($elements as $element)
13591                         {
13592                                 if (is_array($attributes))
13593                                 {
13594                                         foreach ($attributes as $attribute)
13595                                         {
13596                                                 if (isset($element['attribs'][$attribute]['data']))
13597                                                 {
13598                                                         $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13599                                                         $new_element = SimplePie_Misc::element_implode($element);
13600                                                         $data = str_replace($element['full'], $new_element, $data);
13601                                                         $element['full'] = $new_element;
13602                                                 }
13603                                         }
13604                                 }
13605                                 elseif (isset($element['attribs'][$attributes]['data']))
13606                                 {
13607                                         $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13608                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13609                                 }
13610                         }
13611                 }
13612                 return $data;
13613         }
13614
13615         function do_strip_htmltags($match)
13616         {
13617                 if ($this->encode_instead_of_strip)
13618                 {
13619                         if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13620                         {
13621                                 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13622                                 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13623                                 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13624                         }
13625                         else
13626                         {
13627                                 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13628                         }
13629                 }
13630                 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13631                 {
13632                         return $match[4];
13633                 }
13634                 else
13635                 {
13636                         return '';
13637                 }
13638         }
13639 }
13640
13641 ?>