]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/class-simplepie.php
Wordpress 2.8-scripts
[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 (!empty($this->data['items']))
755                 {
756                         foreach ($this->data['items'] as $item)
757                         {
758                                 $item->__destruct();
759                         }
760                         unset($this->data['items']);
761                 }
762                 if (!empty($this->data['ordered_items']))
763                 {
764                         foreach ($this->data['ordered_items'] as $item)
765                         {
766                                 $item->__destruct();
767                         }
768                         unset($this->data['ordered_items']);
769                 }
770         }
771
772         /**
773          * Force the given data/URL to be treated as a feed no matter what it
774          * appears like
775          *
776          * @access public
777          * @since 1.1
778          * @param bool $enable Force the given data/URL to be treated as a feed
779          */
780         function force_feed($enable = false)
781         {
782                 $this->force_feed = (bool) $enable;
783         }
784
785         /**
786          * This is the URL of the feed you want to parse.
787          *
788          * This allows you to enter the URL of the feed you want to parse, or the
789          * website you want to try to use auto-discovery on. This takes priority
790          * over any set raw data.
791          *
792          * You can set multiple feeds to mash together by passing an array instead
793          * of a string for the $url. Remember that with each additional feed comes
794          * additional processing and resources.
795          *
796          * @access public
797          * @since 1.0 Preview Release
798          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
799          * @see SimplePie::set_raw_data()
800          */
801         function set_feed_url($url)
802         {
803                 if (is_array($url))
804                 {
805                         $this->multifeed_url = array();
806                         foreach ($url as $value)
807                         {
808                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
809                         }
810                 }
811                 else
812                 {
813                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
814                 }
815         }
816
817         /**
818          * Provides an instance of SimplePie_File to use as a feed
819          *
820          * @access public
821          * @param object &$file Instance of SimplePie_File (or subclass)
822          * @return bool True on success, false on failure
823          */
824         function set_file(&$file)
825         {
826                 if (is_a($file, 'SimplePie_File'))
827                 {
828                         $this->feed_url = $file->url;
829                         $this->file =& $file;
830                         return true;
831                 }
832                 return false;
833         }
834
835         /**
836          * Allows you to use a string of RSS/Atom data instead of a remote feed.
837          *
838          * If you have a feed available as a string in PHP, you can tell SimplePie
839          * to parse that data string instead of a remote feed. Any set feed URL
840          * takes precedence.
841          *
842          * @access public
843          * @since 1.0 Beta 3
844          * @param string $data RSS or Atom data as a string.
845          * @see SimplePie::set_feed_url()
846          */
847         function set_raw_data($data)
848         {
849                 $this->raw_data = $data;
850         }
851
852         /**
853          * Allows you to override the default timeout for fetching remote feeds.
854          *
855          * This allows you to change the maximum time the feed's server to respond
856          * and send the feed back.
857          *
858          * @access public
859          * @since 1.0 Beta 3
860          * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
861          */
862         function set_timeout($timeout = 10)
863         {
864                 $this->timeout = (int) $timeout;
865         }
866
867         /**
868          * Forces SimplePie to use fsockopen() instead of the preferred cURL
869          * functions.
870          *
871          * @access public
872          * @since 1.0 Beta 3
873          * @param bool $enable Force fsockopen() to be used
874          */
875         function force_fsockopen($enable = false)
876         {
877                 $this->force_fsockopen = (bool) $enable;
878         }
879
880         /**
881          * Outputs the raw XML content of the feed, after it has gone through
882          * SimplePie's filters.
883          *
884          * Used only for debugging, this function will output the XML content as
885          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
886          * before trying to parse it. Many parts of the feed are re-written in
887          * memory, and in the end, you have a parsable feed. XML dump shows you the
888          * actual XML that SimplePie tries to parse, which may or may not be very
889          * different from the original feed.
890          *
891          * @access public
892          * @since 1.0 Preview Release
893          * @param bool $enable Enable XML dump
894          */
895         function enable_xml_dump($enable = false)
896         {
897                 $this->xml_dump = (bool) $enable;
898         }
899
900         /**
901          * Enables/disables caching in SimplePie.
902          *
903          * This option allows you to disable caching all-together in SimplePie.
904          * However, disabling the cache can lead to longer load times.
905          *
906          * @access public
907          * @since 1.0 Preview Release
908          * @param bool $enable Enable caching
909          */
910         function enable_cache($enable = true)
911         {
912                 $this->cache = (bool) $enable;
913         }
914
915         /**
916          * Set the length of time (in seconds) that the contents of a feed
917          * will be cached.
918          *
919          * @access public
920          * @param int $seconds The feed content cache duration.
921          */
922         function set_cache_duration($seconds = 3600)
923         {
924                 $this->cache_duration = (int) $seconds;
925         }
926
927         /**
928          * Set the length of time (in seconds) that the autodiscovered feed
929          * URL will be cached.
930          *
931          * @access public
932          * @param int $seconds The autodiscovered feed URL cache duration.
933          */
934         function set_autodiscovery_cache_duration($seconds = 604800)
935         {
936                 $this->autodiscovery_cache_duration = (int) $seconds;
937         }
938
939         /**
940          * Set the file system location where the cached files should be stored.
941          *
942          * @access public
943          * @param string $location The file system location.
944          */
945         function set_cache_location($location = './cache')
946         {
947                 $this->cache_location = (string) $location;
948         }
949
950         /**
951          * Determines whether feed items should be sorted into reverse chronological order.
952          *
953          * @access public
954          * @param bool $enable Sort as reverse chronological order.
955          */
956         function enable_order_by_date($enable = true)
957         {
958                 $this->order_by_date = (bool) $enable;
959         }
960
961         /**
962          * Allows you to override the character encoding reported by the feed.
963          *
964          * @access public
965          * @param string $encoding Character encoding.
966          */
967         function set_input_encoding($encoding = false)
968         {
969                 if ($encoding)
970                 {
971                         $this->input_encoding = (string) $encoding;
972                 }
973                 else
974                 {
975                         $this->input_encoding = false;
976                 }
977         }
978
979         /**
980          * Set how much feed autodiscovery to do
981          *
982          * @access public
983          * @see SIMPLEPIE_LOCATOR_NONE
984          * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
985          * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
986          * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
987          * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
988          * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
989          * @see SIMPLEPIE_LOCATOR_ALL
990          * @param int $level Feed Autodiscovery Level (level can be a
991          * combination of the above constants, see bitwise OR operator)
992          */
993         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
994         {
995                 $this->autodiscovery = (int) $level;
996         }
997
998         /**
999          * Allows you to change which class SimplePie uses for caching.
1000          * Useful when you are overloading or extending SimplePie's default classes.
1001          *
1002          * @access public
1003          * @param string $class Name of custom class.
1004          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1005          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1006          */
1007         function set_cache_class($class = 'SimplePie_Cache')
1008         {
1009                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1010                 {
1011                         $this->cache_class = $class;
1012                         return true;
1013                 }
1014                 return false;
1015         }
1016
1017         /**
1018          * Allows you to change which class SimplePie uses for auto-discovery.
1019          * Useful when you are overloading or extending SimplePie's default classes.
1020          *
1021          * @access public
1022          * @param string $class Name of custom class.
1023          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1024          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1025          */
1026         function set_locator_class($class = 'SimplePie_Locator')
1027         {
1028                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1029                 {
1030                         $this->locator_class = $class;
1031                         return true;
1032                 }
1033                 return false;
1034         }
1035
1036         /**
1037          * Allows you to change which class SimplePie uses for XML parsing.
1038          * Useful when you are overloading or extending SimplePie's default classes.
1039          *
1040          * @access public
1041          * @param string $class Name of custom class.
1042          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1043          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1044          */
1045         function set_parser_class($class = 'SimplePie_Parser')
1046         {
1047                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1048                 {
1049                         $this->parser_class = $class;
1050                         return true;
1051                 }
1052                 return false;
1053         }
1054
1055         /**
1056          * Allows you to change which class SimplePie uses for remote file fetching.
1057          * Useful when you are overloading or extending SimplePie's default classes.
1058          *
1059          * @access public
1060          * @param string $class Name of custom class.
1061          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1062          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1063          */
1064         function set_file_class($class = 'SimplePie_File')
1065         {
1066                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1067                 {
1068                         $this->file_class = $class;
1069                         return true;
1070                 }
1071                 return false;
1072         }
1073
1074         /**
1075          * Allows you to change which class SimplePie uses for data sanitization.
1076          * Useful when you are overloading or extending SimplePie's default classes.
1077          *
1078          * @access public
1079          * @param string $class Name of custom class.
1080          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1081          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1082          */
1083         function set_sanitize_class($class = 'SimplePie_Sanitize')
1084         {
1085                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1086                 {
1087                         $this->sanitize =& new $class;
1088                         return true;
1089                 }
1090                 return false;
1091         }
1092
1093         /**
1094          * Allows you to change which class SimplePie uses for handling feed items.
1095          * Useful when you are overloading or extending SimplePie's default classes.
1096          *
1097          * @access public
1098          * @param string $class Name of custom class.
1099          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1100          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1101          */
1102         function set_item_class($class = 'SimplePie_Item')
1103         {
1104                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1105                 {
1106                         $this->item_class = $class;
1107                         return true;
1108                 }
1109                 return false;
1110         }
1111
1112         /**
1113          * Allows you to change which class SimplePie uses for handling author data.
1114          * Useful when you are overloading or extending SimplePie's default classes.
1115          *
1116          * @access public
1117          * @param string $class Name of custom class.
1118          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1119          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1120          */
1121         function set_author_class($class = 'SimplePie_Author')
1122         {
1123                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1124                 {
1125                         $this->author_class = $class;
1126                         return true;
1127                 }
1128                 return false;
1129         }
1130
1131         /**
1132          * Allows you to change which class SimplePie uses for handling category data.
1133          * Useful when you are overloading or extending SimplePie's default classes.
1134          *
1135          * @access public
1136          * @param string $class Name of custom class.
1137          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1138          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1139          */
1140         function set_category_class($class = 'SimplePie_Category')
1141         {
1142                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1143                 {
1144                         $this->category_class = $class;
1145                         return true;
1146                 }
1147                 return false;
1148         }
1149
1150         /**
1151          * Allows you to change which class SimplePie uses for feed enclosures.
1152          * Useful when you are overloading or extending SimplePie's default classes.
1153          *
1154          * @access public
1155          * @param string $class Name of custom class.
1156          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1157          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1158          */
1159         function set_enclosure_class($class = 'SimplePie_Enclosure')
1160         {
1161                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1162                 {
1163                         $this->enclosure_class = $class;
1164                         return true;
1165                 }
1166                 return false;
1167         }
1168
1169         /**
1170          * Allows you to change which class SimplePie uses for <media:text> captions
1171          * Useful when you are overloading or extending SimplePie's default classes.
1172          *
1173          * @access public
1174          * @param string $class Name of custom class.
1175          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1176          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1177          */
1178         function set_caption_class($class = 'SimplePie_Caption')
1179         {
1180                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1181                 {
1182                         $this->caption_class = $class;
1183                         return true;
1184                 }
1185                 return false;
1186         }
1187
1188         /**
1189          * Allows you to change which class SimplePie uses for <media:copyright>
1190          * Useful when you are overloading or extending SimplePie's default classes.
1191          *
1192          * @access public
1193          * @param string $class Name of custom class.
1194          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1195          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1196          */
1197         function set_copyright_class($class = 'SimplePie_Copyright')
1198         {
1199                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1200                 {
1201                         $this->copyright_class = $class;
1202                         return true;
1203                 }
1204                 return false;
1205         }
1206
1207         /**
1208          * Allows you to change which class SimplePie uses for <media:credit>
1209          * Useful when you are overloading or extending SimplePie's default classes.
1210          *
1211          * @access public
1212          * @param string $class Name of custom class.
1213          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1214          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1215          */
1216         function set_credit_class($class = 'SimplePie_Credit')
1217         {
1218                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1219                 {
1220                         $this->credit_class = $class;
1221                         return true;
1222                 }
1223                 return false;
1224         }
1225
1226         /**
1227          * Allows you to change which class SimplePie uses for <media:rating>
1228          * Useful when you are overloading or extending SimplePie's default classes.
1229          *
1230          * @access public
1231          * @param string $class Name of custom class.
1232          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1233          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1234          */
1235         function set_rating_class($class = 'SimplePie_Rating')
1236         {
1237                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1238                 {
1239                         $this->rating_class = $class;
1240                         return true;
1241                 }
1242                 return false;
1243         }
1244
1245         /**
1246          * Allows you to change which class SimplePie uses for <media:restriction>
1247          * Useful when you are overloading or extending SimplePie's default classes.
1248          *
1249          * @access public
1250          * @param string $class Name of custom class.
1251          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1252          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1253          */
1254         function set_restriction_class($class = 'SimplePie_Restriction')
1255         {
1256                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1257                 {
1258                         $this->restriction_class = $class;
1259                         return true;
1260                 }
1261                 return false;
1262         }
1263
1264         /**
1265          * Allows you to change which class SimplePie uses for content-type sniffing.
1266          * Useful when you are overloading or extending SimplePie's default classes.
1267          *
1268          * @access public
1269          * @param string $class Name of custom class.
1270          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1271          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1272          */
1273         function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1274         {
1275                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1276                 {
1277                         $this->content_type_sniffer_class = $class;
1278                         return true;
1279                 }
1280                 return false;
1281         }
1282
1283         /**
1284          * Allows you to change which class SimplePie uses item sources.
1285          * Useful when you are overloading or extending SimplePie's default classes.
1286          *
1287          * @access public
1288          * @param string $class Name of custom class.
1289          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1290          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1291          */
1292         function set_source_class($class = 'SimplePie_Source')
1293         {
1294                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1295                 {
1296                         $this->source_class = $class;
1297                         return true;
1298                 }
1299                 return false;
1300         }
1301
1302         /**
1303          * Allows you to override the default user agent string.
1304          *
1305          * @access public
1306          * @param string $ua New user agent string.
1307          */
1308         function set_useragent($ua = SIMPLEPIE_USERAGENT)
1309         {
1310                 $this->useragent = (string) $ua;
1311         }
1312
1313         /**
1314          * Set callback function to create cache filename with
1315          *
1316          * @access public
1317          * @param mixed $function Callback function
1318          */
1319         function set_cache_name_function($function = 'md5')
1320         {
1321                 if (is_callable($function))
1322                 {
1323                         $this->cache_name_function = $function;
1324                 }
1325         }
1326
1327         /**
1328          * Set javascript query string parameter
1329          *
1330          * @access public
1331          * @param mixed $get Javascript query string parameter
1332          */
1333         function set_javascript($get = 'js')
1334         {
1335                 if ($get)
1336                 {
1337                         $this->javascript = (string) $get;
1338                 }
1339                 else
1340                 {
1341                         $this->javascript = false;
1342                 }
1343         }
1344
1345         /**
1346          * Set options to make SP as fast as possible.  Forgoes a
1347          * substantial amount of data sanitization in favor of speed.
1348          *
1349          * @access public
1350          * @param bool $set Whether to set them or not
1351          */
1352         function set_stupidly_fast($set = false)
1353         {
1354                 if ($set)
1355                 {
1356                         $this->enable_order_by_date(false);
1357                         $this->remove_div(false);
1358                         $this->strip_comments(false);
1359                         $this->strip_htmltags(false);
1360                         $this->strip_attributes(false);
1361                         $this->set_image_handler(false);
1362                 }
1363         }
1364
1365         /**
1366          * Set maximum number of feeds to check with autodiscovery
1367          *
1368          * @access public
1369          * @param int $max Maximum number of feeds to check
1370          */
1371         function set_max_checked_feeds($max = 10)
1372         {
1373                 $this->max_checked_feeds = (int) $max;
1374         }
1375
1376         function remove_div($enable = true)
1377         {
1378                 $this->sanitize->remove_div($enable);
1379         }
1380
1381         function strip_htmltags($tags = '', $encode = null)
1382         {
1383                 if ($tags === '')
1384                 {
1385                         $tags = $this->strip_htmltags;
1386                 }
1387                 $this->sanitize->strip_htmltags($tags);
1388                 if ($encode !== null)
1389                 {
1390                         $this->sanitize->encode_instead_of_strip($tags);
1391                 }
1392         }
1393
1394         function encode_instead_of_strip($enable = true)
1395         {
1396                 $this->sanitize->encode_instead_of_strip($enable);
1397         }
1398
1399         function strip_attributes($attribs = '')
1400         {
1401                 if ($attribs === '')
1402                 {
1403                         $attribs = $this->strip_attributes;
1404                 }
1405                 $this->sanitize->strip_attributes($attribs);
1406         }
1407
1408         function set_output_encoding($encoding = 'UTF-8')
1409         {
1410                 $this->sanitize->set_output_encoding($encoding);
1411         }
1412
1413         function strip_comments($strip = false)
1414         {
1415                 $this->sanitize->strip_comments($strip);
1416         }
1417
1418         /**
1419          * Set element/attribute key/value pairs of HTML attributes
1420          * containing URLs that need to be resolved relative to the feed
1421          *
1422          * @access public
1423          * @since 1.0
1424          * @param array $element_attribute Element/attribute key/value pairs
1425          */
1426         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'))
1427         {
1428                 $this->sanitize->set_url_replacements($element_attribute);
1429         }
1430
1431         /**
1432          * Set the handler to enable the display of cached favicons.
1433          *
1434          * @access public
1435          * @param str $page Web-accessible path to the handler_favicon.php file.
1436          * @param str $qs The query string that the value should be passed to.
1437          */
1438         function set_favicon_handler($page = false, $qs = 'i')
1439         {
1440                 if ($page != false)
1441                 {
1442                         $this->favicon_handler = $page . '?' . $qs . '=';
1443                 }
1444                 else
1445                 {
1446                         $this->favicon_handler = '';
1447                 }
1448         }
1449
1450         /**
1451          * Set the handler to enable the display of cached images.
1452          *
1453          * @access public
1454          * @param str $page Web-accessible path to the handler_image.php file.
1455          * @param str $qs The query string that the value should be passed to.
1456          */
1457         function set_image_handler($page = false, $qs = 'i')
1458         {
1459                 if ($page != false)
1460                 {
1461                         $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1462                 }
1463                 else
1464                 {
1465                         $this->image_handler = '';
1466                 }
1467         }
1468
1469         /**
1470          * Set the limit for items returned per-feed with multifeeds.
1471          *
1472          * @access public
1473          * @param integer $limit The maximum number of items to return.
1474          */
1475         function set_item_limit($limit = 0)
1476         {
1477                 $this->item_limit = (int) $limit;
1478         }
1479
1480         function init()
1481         {
1482                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1483                 {
1484                         return false;
1485                 }
1486                 if (isset($_GET[$this->javascript]))
1487                 {
1488                         if (function_exists('ob_gzhandler'))
1489                         {
1490                                 ob_start('ob_gzhandler');
1491                         }
1492                         header('Content-type: text/javascript; charset: UTF-8');
1493                         header('Cache-Control: must-revalidate');
1494                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1495                         ?>
1496 function embed_odeo(link) {
1497         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>');
1498 }
1499
1500 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1501         if (placeholder != '') {
1502                 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>');
1503         }
1504         else {
1505                 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>');
1506         }
1507 }
1508
1509 function embed_flash(bgcolor, width, height, link, loop, type) {
1510         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>');
1511 }
1512
1513 function embed_flv(width, height, link, placeholder, loop, player) {
1514         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>');
1515 }
1516
1517 function embed_wmedia(width, height, link) {
1518         document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1519 }
1520                         <?php
1521                         exit;
1522                 }
1523
1524                 // Pass whatever was set with config options over to the sanitizer.
1525                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1526                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1527
1528                 if ($this->feed_url !== null || $this->raw_data !== null)
1529                 {
1530                         $this->data = array();
1531                         $this->multifeed_objects = array();
1532                         $cache = false;
1533
1534                         if ($this->feed_url !== null)
1535                         {
1536                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1537                                 // Decide whether to enable caching
1538                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1539                                 {
1540                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1541                                 }
1542                                 // If it's enabled and we don't want an XML dump, use the cache
1543                                 if ($cache && !$this->xml_dump)
1544                                 {
1545                                         // Load the Cache
1546                                         $this->data = $cache->load();
1547                                         if (!empty($this->data))
1548                                         {
1549                                                 // If the cache is for an outdated build of SimplePie
1550                                                 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1551                                                 {
1552                                                         $cache->unlink();
1553                                                         $this->data = array();
1554                                                 }
1555                                                 // If we've hit a collision just rerun it with caching disabled
1556                                                 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1557                                                 {
1558                                                         $cache = false;
1559                                                         $this->data = array();
1560                                                 }
1561                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1562                                                 elseif (isset($this->data['feed_url']))
1563                                                 {
1564                                                         // If the autodiscovery cache is still valid use it.
1565                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1566                                                         {
1567                                                                 // Do not need to do feed autodiscovery yet.
1568                                                                 if ($this->data['feed_url'] == $this->data['url'])
1569                                                                 {
1570                                                                         $cache->unlink();
1571                                                                         $this->data = array();
1572                                                                 }
1573                                                                 else
1574                                                                 {
1575                                                                         $this->set_feed_url($this->data['feed_url']);
1576                                                                         return $this->init();
1577                                                                 }
1578                                                         }
1579                                                 }
1580                                                 // Check if the cache has been updated
1581                                                 elseif ($cache->mtime() + $this->cache_duration < time())
1582                                                 {
1583                                                         // If we have last-modified and/or etag set
1584                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1585                                                         {
1586                                                                 $headers = array();
1587                                                                 if (isset($this->data['headers']['last-modified']))
1588                                                                 {
1589                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1590                                                                 }
1591                                                                 if (isset($this->data['headers']['etag']))
1592                                                                 {
1593                                                                         $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1594                                                                 }
1595                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1596                                                                 if ($file->success)
1597                                                                 {
1598                                                                         if ($file->status_code == 304)
1599                                                                         {
1600                                                                                 $cache->touch();
1601                                                                                 return true;
1602                                                                         }
1603                                                                         else
1604                                                                         {
1605                                                                                 $headers = $file->headers;
1606                                                                         }
1607                                                                 }
1608                                                                 else
1609                                                                 {
1610                                                                         unset($file);
1611                                                                 }
1612                                                         }
1613                                                 }
1614                                                 // If the cache is still valid, just return true
1615                                                 else
1616                                                 {
1617                                                         return true;
1618                                                 }
1619                                         }
1620                                         // If the cache is empty, delete it
1621                                         else
1622                                         {
1623                                                 $cache->unlink();
1624                                                 $this->data = array();
1625                                         }
1626                                 }
1627                                 // 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.
1628                                 if (!isset($file))
1629                                 {
1630                                         if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1631                                         {
1632                                                 $file =& $this->file;
1633                                         }
1634                                         else
1635                                         {
1636                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1637                                         }
1638                                 }
1639                                 // If the file connection has an error, set SimplePie::error to that and quit
1640                                 if (!$file->success)
1641                                 {
1642                                         $this->error = $file->error;
1643                                         if (!empty($this->data))
1644                                         {
1645                                                 return true;
1646                                         }
1647                                         else
1648                                         {
1649                                                 return false;
1650                                         }
1651                                 }
1652
1653                                 if (!$this->force_feed)
1654                                 {
1655                                         // Check if the supplied URL is a feed, if it isn't, look for it.
1656                                         $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1657                                         if (!$locate->is_feed($file))
1658                                         {
1659                                                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1660                                                 unset($file);
1661                                                 if ($file = $locate->find($this->autodiscovery))
1662                                                 {
1663                                                         if ($cache)
1664                                                         {
1665                                                                 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1666                                                                 if (!$cache->save($this))
1667                                                                 {
1668                                                                         trigger_error("$cache->name is not writeable", E_USER_WARNING);
1669                                                                 }
1670                                                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1671                                                         }
1672                                                         $this->feed_url = $file->url;
1673                                                 }
1674                                                 else
1675                                                 {
1676                                                         $this->error = "A feed could not be found at $this->feed_url";
1677                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1678                                                         return false;
1679                                                 }
1680                                         }
1681                                         $locate = null;
1682                                 }
1683
1684                                 $headers = $file->headers;
1685                                 $data = $file->body;
1686                                 $sniffer = new $this->content_type_sniffer_class($file);
1687                                 $sniffed = $sniffer->get_type();
1688                         }
1689                         else
1690                         {
1691                                 $data = $this->raw_data;
1692                         }
1693
1694                         // Set up array of possible encodings
1695                         $encodings = array();
1696
1697                         // First check to see if input has been overridden.
1698                         if ($this->input_encoding !== false)
1699                         {
1700                                 $encodings[] = $this->input_encoding;
1701                         }
1702
1703                         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1704                         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1705
1706                         // RFC 3023 (only applies to sniffed content)
1707                         if (isset($sniffed))
1708                         {
1709                                 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1710                                 {
1711                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1712                                         {
1713                                                 $encodings[] = strtoupper($charset[1]);
1714                                         }
1715                                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1716                                         $encodings[] = 'UTF-8';
1717                                 }
1718                                 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1719                                 {
1720                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1721                                         {
1722                                                 $encodings[] = $charset[1];
1723                                         }
1724                                         $encodings[] = 'US-ASCII';
1725                                 }
1726                                 // Text MIME-type default
1727                                 elseif (substr($sniffed, 0, 5) === 'text/')
1728                                 {
1729                                         $encodings[] = 'US-ASCII';
1730                                 }
1731                         }
1732
1733                         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1734                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1735                         $encodings[] = 'UTF-8';
1736                         $encodings[] = 'ISO-8859-1';
1737
1738                         // There's no point in trying an encoding twice
1739                         $encodings = array_unique($encodings);
1740
1741                         // If we want the XML, just output that with the most likely encoding and quit
1742                         if ($this->xml_dump)
1743                         {
1744                                 header('Content-type: text/xml; charset=' . $encodings[0]);
1745                                 echo $data;
1746                                 exit;
1747                         }
1748
1749                         // Loop through each possible encoding, till we return something, or run out of possibilities
1750                         foreach ($encodings as $encoding)
1751                         {
1752                                 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1753                                 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1754                                 {
1755                                         // Create new parser
1756                                         $parser =& new $this->parser_class();
1757
1758                                         // If it's parsed fine
1759                                         if ($parser->parse($utf8_data, 'UTF-8'))
1760                                         {
1761                                                 $this->data = $parser->get_data();
1762                                                 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1763                                                 {
1764                                                         if (isset($headers))
1765                                                         {
1766                                                                 $this->data['headers'] = $headers;
1767                                                         }
1768                                                         $this->data['build'] = SIMPLEPIE_BUILD;
1769
1770                                                         // Cache the file if caching is enabled
1771                                                         if ($cache && !$cache->save($this))
1772                                                         {
1773                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1774                                                         }
1775                                                         return true;
1776                                                 }
1777                                                 else
1778                                                 {
1779                                                         $this->error = "A feed could not be found at $this->feed_url";
1780                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1781                                                         return false;
1782                                                 }
1783                                         }
1784                                 }
1785                         }
1786                         // We have an error, just set SimplePie::error to it and quit
1787                         $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1788                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1789                         return false;
1790                 }
1791                 elseif (!empty($this->multifeed_url))
1792                 {
1793                         $i = 0;
1794                         $success = 0;
1795                         $this->multifeed_objects = array();
1796                         foreach ($this->multifeed_url as $url)
1797                         {
1798                                 if (SIMPLEPIE_PHP5)
1799                                 {
1800                                         // This keyword needs to defy coding standards for PHP4 compatibility
1801                                         $this->multifeed_objects[$i] = clone($this);
1802                                 }
1803                                 else
1804                                 {
1805                                         $this->multifeed_objects[$i] = $this;
1806                                 }
1807                                 $this->multifeed_objects[$i]->set_feed_url($url);
1808                                 $success |= $this->multifeed_objects[$i]->init();
1809                                 $i++;
1810                         }
1811                         return (bool) $success;
1812                 }
1813                 else
1814                 {
1815                         return false;
1816                 }
1817         }
1818
1819         /**
1820          * Return the error message for the occured error
1821          *
1822          * @access public
1823          * @return string Error message
1824          */
1825         function error()
1826         {
1827                 return $this->error;
1828         }
1829
1830         function get_encoding()
1831         {
1832                 return $this->sanitize->output_encoding;
1833         }
1834
1835         function handle_content_type($mime = 'text/html')
1836         {
1837                 if (!headers_sent())
1838                 {
1839                         $header = "Content-type: $mime;";
1840                         if ($this->get_encoding())
1841                         {
1842                                 $header .= ' charset=' . $this->get_encoding();
1843                         }
1844                         else
1845                         {
1846                                 $header .= ' charset=UTF-8';
1847                         }
1848                         header($header);
1849                 }
1850         }
1851
1852         function get_type()
1853         {
1854                 if (!isset($this->data['type']))
1855                 {
1856                         $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1857                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1858                         {
1859                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1860                         }
1861                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1862                         {
1863                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1864                         }
1865                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1866                         {
1867                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1868                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1869                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1870                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1871                                 {
1872                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1873                                 }
1874                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1875                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1876                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1877                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1878                                 {
1879                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1880                                 }
1881                         }
1882                         elseif (isset($this->data['child']['']['rss']))
1883                         {
1884                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1885                                 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1886                                 {
1887                                         switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1888                                         {
1889                                                 case '0.91':
1890                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1891                                                         if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1892                                                         {
1893                                                                 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1894                                                                 {
1895                                                                         case '0':
1896                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1897                                                                                 break;
1898
1899                                                                         case '24':
1900                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1901                                                                                 break;
1902                                                                 }
1903                                                         }
1904                                                         break;
1905
1906                                                 case '0.92':
1907                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1908                                                         break;
1909
1910                                                 case '0.93':
1911                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1912                                                         break;
1913
1914                                                 case '0.94':
1915                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1916                                                         break;
1917
1918                                                 case '2.0':
1919                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1920                                                         break;
1921                                         }
1922                                 }
1923                         }
1924                         else
1925                         {
1926                                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1927                         }
1928                 }
1929                 return $this->data['type'];
1930         }
1931
1932         /**
1933          * Returns the URL for the favicon of the feed's website.
1934          *
1935          * @todo Cache atom:icon
1936          * @access public
1937          * @since 1.0
1938          */
1939         function get_favicon()
1940         {
1941                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1942                 {
1943                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1944                 }
1945                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1946                 {
1947                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1948
1949                         if ($this->cache && $this->favicon_handler)
1950                         {
1951                                 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1952                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1953
1954                                 if ($cache->load())
1955                                 {
1956                                         return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1957                                 }
1958                                 else
1959                                 {
1960                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1961
1962                                         if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1963                                         {
1964                                                 $sniffer = new $this->content_type_sniffer_class($file);
1965                                                 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1966                                                 {
1967                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1968                                                         {
1969                                                                 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1970                                                         }
1971                                                         else
1972                                                         {
1973                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1974                                                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1975                                                         }
1976                                                 }
1977                                         }
1978                                 }
1979                         }
1980                         else
1981                         {
1982                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1983                         }
1984                 }
1985                 return false;
1986         }
1987
1988         /**
1989          * @todo If we have a perm redirect we should return the new URL
1990          * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1991          * @todo Also, |atom:link|@rel=self
1992          */
1993         function subscribe_url()
1994         {
1995                 if ($this->feed_url !== null)
1996                 {
1997                         return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1998                 }
1999                 else
2000                 {
2001                         return null;
2002                 }
2003         }
2004
2005         function subscribe_feed()
2006         {
2007                 if ($this->feed_url !== null)
2008                 {
2009                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2010                 }
2011                 else
2012                 {
2013                         return null;
2014                 }
2015         }
2016
2017         function subscribe_outlook()
2018         {
2019                 if ($this->feed_url !== null)
2020                 {
2021                         return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2022                 }
2023                 else
2024                 {
2025                         return null;
2026                 }
2027         }
2028
2029         function subscribe_podcast()
2030         {
2031                 if ($this->feed_url !== null)
2032                 {
2033                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2034                 }
2035                 else
2036                 {
2037                         return null;
2038                 }
2039         }
2040
2041         function subscribe_itunes()
2042         {
2043                 if ($this->feed_url !== null)
2044                 {
2045                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2046                 }
2047                 else
2048                 {
2049                         return null;
2050                 }
2051         }
2052
2053         /**
2054          * Creates the subscribe_* methods' return data
2055          *
2056          * @access private
2057          * @param string $feed_url String to prefix to the feed URL
2058          * @param string $site_url String to prefix to the site URL (and
2059          * suffix to the feed URL)
2060          * @return mixed URL if feed exists, false otherwise
2061          */
2062         function subscribe_service($feed_url, $site_url = null)
2063         {
2064                 if ($this->subscribe_url())
2065                 {
2066                         $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2067                         if ($site_url !== null && $this->get_link() !== null)
2068                         {
2069                                 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2070                         }
2071                         return $return;
2072                 }
2073                 else
2074                 {
2075                         return null;
2076                 }
2077         }
2078
2079         function subscribe_aol()
2080         {
2081                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2082         }
2083
2084         function subscribe_bloglines()
2085         {
2086                 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2087         }
2088
2089         function subscribe_eskobo()
2090         {
2091                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2092         }
2093
2094         function subscribe_feedfeeds()
2095         {
2096                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2097         }
2098
2099         function subscribe_feedster()
2100         {
2101                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2102         }
2103
2104         function subscribe_google()
2105         {
2106                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2107         }
2108
2109         function subscribe_gritwire()
2110         {
2111                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2112         }
2113
2114         function subscribe_msn()
2115         {
2116                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2117         }
2118
2119         function subscribe_netvibes()
2120         {
2121                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2122         }
2123
2124         function subscribe_newsburst()
2125         {
2126                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2127         }
2128
2129         function subscribe_newsgator()
2130         {
2131                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2132         }
2133
2134         function subscribe_odeo()
2135         {
2136                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2137         }
2138
2139         function subscribe_podnova()
2140         {
2141                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2142         }
2143
2144         function subscribe_rojo()
2145         {
2146                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2147         }
2148
2149         function subscribe_yahoo()
2150         {
2151                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2152         }
2153
2154         function get_feed_tags($namespace, $tag)
2155         {
2156                 $type = $this->get_type();
2157                 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2158                 {
2159                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2160                         {
2161                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2162                         }
2163                 }
2164                 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2165                 {
2166                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2167                         {
2168                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2169                         }
2170                 }
2171                 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2172                 {
2173                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2174                         {
2175                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2176                         }
2177                 }
2178                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2179                 {
2180                         if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2181                         {
2182                                 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2183                         }
2184                 }
2185                 return null;
2186         }
2187
2188         function get_channel_tags($namespace, $tag)
2189         {
2190                 $type = $this->get_type();
2191                 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2192                 {
2193                         if ($return = $this->get_feed_tags($namespace, $tag))
2194                         {
2195                                 return $return;
2196                         }
2197                 }
2198                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2199                 {
2200                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2201                         {
2202                                 if (isset($channel[0]['child'][$namespace][$tag]))
2203                                 {
2204                                         return $channel[0]['child'][$namespace][$tag];
2205                                 }
2206                         }
2207                 }
2208                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2209                 {
2210                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2211                         {
2212                                 if (isset($channel[0]['child'][$namespace][$tag]))
2213                                 {
2214                                         return $channel[0]['child'][$namespace][$tag];
2215                                 }
2216                         }
2217                 }
2218                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2219                 {
2220                         if ($channel = $this->get_feed_tags('', 'channel'))
2221                         {
2222                                 if (isset($channel[0]['child'][$namespace][$tag]))
2223                                 {
2224                                         return $channel[0]['child'][$namespace][$tag];
2225                                 }
2226                         }
2227                 }
2228                 return null;
2229         }
2230
2231         function get_image_tags($namespace, $tag)
2232         {
2233                 $type = $this->get_type();
2234                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2235                 {
2236                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2237                         {
2238                                 if (isset($image[0]['child'][$namespace][$tag]))
2239                                 {
2240                                         return $image[0]['child'][$namespace][$tag];
2241                                 }
2242                         }
2243                 }
2244                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2245                 {
2246                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2247                         {
2248                                 if (isset($image[0]['child'][$namespace][$tag]))
2249                                 {
2250                                         return $image[0]['child'][$namespace][$tag];
2251                                 }
2252                         }
2253                 }
2254                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2255                 {
2256                         if ($image = $this->get_channel_tags('', 'image'))
2257                         {
2258                                 if (isset($image[0]['child'][$namespace][$tag]))
2259                                 {
2260                                         return $image[0]['child'][$namespace][$tag];
2261                                 }
2262                         }
2263                 }
2264                 return null;
2265         }
2266
2267         function get_base($element = array())
2268         {
2269                 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2270                 {
2271                         return $element['xml_base'];
2272                 }
2273                 elseif ($this->get_link() !== null)
2274                 {
2275                         return $this->get_link();
2276                 }
2277                 else
2278                 {
2279                         return $this->subscribe_url();
2280                 }
2281         }
2282
2283         function sanitize($data, $type, $base = '')
2284         {
2285                 return $this->sanitize->sanitize($data, $type, $base);
2286         }
2287
2288         function get_title()
2289         {
2290                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2291                 {
2292                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2293                 }
2294                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2295                 {
2296                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2297                 }
2298                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2299                 {
2300                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2301                 }
2302                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2303                 {
2304                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305                 }
2306                 elseif ($return = $this->get_channel_tags('', 'title'))
2307                 {
2308                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2309                 }
2310                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2311                 {
2312                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2313                 }
2314                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2315                 {
2316                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2317                 }
2318                 else
2319                 {
2320                         return null;
2321                 }
2322         }
2323
2324         function get_category($key = 0)
2325         {
2326                 $categories = $this->get_categories();
2327                 if (isset($categories[$key]))
2328                 {
2329                         return $categories[$key];
2330                 }
2331                 else
2332                 {
2333                         return null;
2334                 }
2335         }
2336
2337         function get_categories()
2338         {
2339                 $categories = array();
2340
2341                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2342                 {
2343                         $term = null;
2344                         $scheme = null;
2345                         $label = null;
2346                         if (isset($category['attribs']['']['term']))
2347                         {
2348                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2349                         }
2350                         if (isset($category['attribs']['']['scheme']))
2351                         {
2352                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2353                         }
2354                         if (isset($category['attribs']['']['label']))
2355                         {
2356                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2357                         }
2358                         $categories[] =& new $this->category_class($term, $scheme, $label);
2359                 }
2360                 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2361                 {
2362                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2363                 }
2364                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2365                 {
2366                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367                 }
2368                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2369                 {
2370                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371                 }
2372
2373                 if (!empty($categories))
2374                 {
2375                         return SimplePie_Misc::array_unique($categories);
2376                 }
2377                 else
2378                 {
2379                         return null;
2380                 }
2381         }
2382
2383         function get_author($key = 0)
2384         {
2385                 $authors = $this->get_authors();
2386                 if (isset($authors[$key]))
2387                 {
2388                         return $authors[$key];
2389                 }
2390                 else
2391                 {
2392                         return null;
2393                 }
2394         }
2395
2396         function get_authors()
2397         {
2398                 $authors = array();
2399                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2400                 {
2401                         $name = null;
2402                         $uri = null;
2403                         $email = null;
2404                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2405                         {
2406                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2407                         }
2408                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2409                         {
2410                                 $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]));
2411                         }
2412                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2413                         {
2414                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2415                         }
2416                         if ($name !== null || $email !== null || $uri !== null)
2417                         {
2418                                 $authors[] =& new $this->author_class($name, $uri, $email);
2419                         }
2420                 }
2421                 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2422                 {
2423                         $name = null;
2424                         $url = null;
2425                         $email = null;
2426                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2427                         {
2428                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2429                         }
2430                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2431                         {
2432                                 $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]));
2433                         }
2434                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2435                         {
2436                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2437                         }
2438                         if ($name !== null || $email !== null || $url !== null)
2439                         {
2440                                 $authors[] =& new $this->author_class($name, $url, $email);
2441                         }
2442                 }
2443                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2444                 {
2445                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2446                 }
2447                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2448                 {
2449                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450                 }
2451                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2452                 {
2453                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454                 }
2455
2456                 if (!empty($authors))
2457                 {
2458                         return SimplePie_Misc::array_unique($authors);
2459                 }
2460                 else
2461                 {
2462                         return null;
2463                 }
2464         }
2465
2466         function get_contributor($key = 0)
2467         {
2468                 $contributors = $this->get_contributors();
2469                 if (isset($contributors[$key]))
2470                 {
2471                         return $contributors[$key];
2472                 }
2473                 else
2474                 {
2475                         return null;
2476                 }
2477         }
2478
2479         function get_contributors()
2480         {
2481                 $contributors = array();
2482                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2483                 {
2484                         $name = null;
2485                         $uri = null;
2486                         $email = null;
2487                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2488                         {
2489                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2490                         }
2491                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2492                         {
2493                                 $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]));
2494                         }
2495                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2496                         {
2497                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2498                         }
2499                         if ($name !== null || $email !== null || $uri !== null)
2500                         {
2501                                 $contributors[] =& new $this->author_class($name, $uri, $email);
2502                         }
2503                 }
2504                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2505                 {
2506                         $name = null;
2507                         $url = null;
2508                         $email = null;
2509                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2510                         {
2511                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2512                         }
2513                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2514                         {
2515                                 $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]));
2516                         }
2517                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2518                         {
2519                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2520                         }
2521                         if ($name !== null || $email !== null || $url !== null)
2522                         {
2523                                 $contributors[] =& new $this->author_class($name, $url, $email);
2524                         }
2525                 }
2526
2527                 if (!empty($contributors))
2528                 {
2529                         return SimplePie_Misc::array_unique($contributors);
2530                 }
2531                 else
2532                 {
2533                         return null;
2534                 }
2535         }
2536
2537         function get_link($key = 0, $rel = 'alternate')
2538         {
2539                 $links = $this->get_links($rel);
2540                 if (isset($links[$key]))
2541                 {
2542                         return $links[$key];
2543                 }
2544                 else
2545                 {
2546                         return null;
2547                 }
2548         }
2549
2550         /**
2551          * Added for parity between the parent-level and the item/entry-level.
2552          */
2553         function get_permalink()
2554         {
2555                 return $this->get_link(0);
2556         }
2557
2558         function get_links($rel = 'alternate')
2559         {
2560                 if (!isset($this->data['links']))
2561                 {
2562                         $this->data['links'] = array();
2563                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2564                         {
2565                                 foreach ($links as $link)
2566                                 {
2567                                         if (isset($link['attribs']['']['href']))
2568                                         {
2569                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2570                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2571                                         }
2572                                 }
2573                         }
2574                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2575                         {
2576                                 foreach ($links as $link)
2577                                 {
2578                                         if (isset($link['attribs']['']['href']))
2579                                         {
2580                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2581                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2582
2583                                         }
2584                                 }
2585                         }
2586                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2587                         {
2588                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2589                         }
2590                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2591                         {
2592                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2593                         }
2594                         if ($links = $this->get_channel_tags('', 'link'))
2595                         {
2596                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2597                         }
2598
2599                         $keys = array_keys($this->data['links']);
2600                         foreach ($keys as $key)
2601                         {
2602                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
2603                                 {
2604                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2605                                         {
2606                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2607                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2608                                         }
2609                                         else
2610                                         {
2611                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2612                                         }
2613                                 }
2614                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2615                                 {
2616                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2617                                 }
2618                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2619                         }
2620                 }
2621
2622                 if (isset($this->data['links'][$rel]))
2623                 {
2624                         return $this->data['links'][$rel];
2625                 }
2626                 else
2627                 {
2628                         return null;
2629                 }
2630         }
2631
2632         function get_description()
2633         {
2634                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2635                 {
2636                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2637                 }
2638                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2639                 {
2640                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2641                 }
2642                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2643                 {
2644                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2645                 }
2646                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2647                 {
2648                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649                 }
2650                 elseif ($return = $this->get_channel_tags('', 'description'))
2651                 {
2652                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2653                 }
2654                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2655                 {
2656                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2657                 }
2658                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2659                 {
2660                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2661                 }
2662                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2663                 {
2664                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2665                 }
2666                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2667                 {
2668                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2669                 }
2670                 else
2671                 {
2672                         return null;
2673                 }
2674         }
2675
2676         function get_copyright()
2677         {
2678                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2679                 {
2680                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2681                 }
2682                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2683                 {
2684                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2685                 }
2686                 elseif ($return = $this->get_channel_tags('', 'copyright'))
2687                 {
2688                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2689                 }
2690                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2691                 {
2692                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2693                 }
2694                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2695                 {
2696                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697                 }
2698                 else
2699                 {
2700                         return null;
2701                 }
2702         }
2703
2704         function get_language()
2705         {
2706                 if ($return = $this->get_channel_tags('', 'language'))
2707                 {
2708                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2709                 }
2710                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2711                 {
2712                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713                 }
2714                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2715                 {
2716                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717                 }
2718                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2719                 {
2720                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2721                 }
2722                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2723                 {
2724                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725                 }
2726                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2727                 {
2728                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2729                 }
2730                 elseif (isset($this->data['headers']['content-language']))
2731                 {
2732                         return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2733                 }
2734                 else
2735                 {
2736                         return null;
2737                 }
2738         }
2739
2740         function get_latitude()
2741         {
2742                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2743                 {
2744                         return (float) $return[0]['data'];
2745                 }
2746                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2747                 {
2748                         return (float) $match[1];
2749                 }
2750                 else
2751                 {
2752                         return null;
2753                 }
2754         }
2755
2756         function get_longitude()
2757         {
2758                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2759                 {
2760                         return (float) $return[0]['data'];
2761                 }
2762                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2763                 {
2764                         return (float) $return[0]['data'];
2765                 }
2766                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2767                 {
2768                         return (float) $match[2];
2769                 }
2770                 else
2771                 {
2772                         return null;
2773                 }
2774         }
2775
2776         function get_image_title()
2777         {
2778                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2779                 {
2780                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781                 }
2782                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2783                 {
2784                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785                 }
2786                 elseif ($return = $this->get_image_tags('', 'title'))
2787                 {
2788                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789                 }
2790                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2791                 {
2792                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2793                 }
2794                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2795                 {
2796                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2797                 }
2798                 else
2799                 {
2800                         return null;
2801                 }
2802         }
2803
2804         function get_image_url()
2805         {
2806                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2807                 {
2808                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2809                 }
2810                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2811                 {
2812                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813                 }
2814                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2815                 {
2816                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817                 }
2818                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2819                 {
2820                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821                 }
2822                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2823                 {
2824                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2825                 }
2826                 elseif ($return = $this->get_image_tags('', 'url'))
2827                 {
2828                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829                 }
2830                 else
2831                 {
2832                         return null;
2833                 }
2834         }
2835
2836         function get_image_link()
2837         {
2838                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2839                 {
2840                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2841                 }
2842                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2843                 {
2844                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2845                 }
2846                 elseif ($return = $this->get_image_tags('', 'link'))
2847                 {
2848                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2849                 }
2850                 else
2851                 {
2852                         return null;
2853                 }
2854         }
2855
2856         function get_image_width()
2857         {
2858                 if ($return = $this->get_image_tags('', 'width'))
2859                 {
2860                         return round($return[0]['data']);
2861                 }
2862                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2863                 {
2864                         return 88.0;
2865                 }
2866                 else
2867                 {
2868                         return null;
2869                 }
2870         }
2871
2872         function get_image_height()
2873         {
2874                 if ($return = $this->get_image_tags('', 'height'))
2875                 {
2876                         return round($return[0]['data']);
2877                 }
2878                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2879                 {
2880                         return 31.0;
2881                 }
2882                 else
2883                 {
2884                         return null;
2885                 }
2886         }
2887
2888         function get_item_quantity($max = 0)
2889         {
2890                 $qty = count($this->get_items());
2891                 if ($max == 0)
2892                 {
2893                         return $qty;
2894                 }
2895                 else
2896                 {
2897                         return ($qty > $max) ? $max : $qty;
2898                 }
2899         }
2900
2901         function get_item($key = 0)
2902         {
2903                 $items = $this->get_items();
2904                 if (isset($items[$key]))
2905                 {
2906                         return $items[$key];
2907                 }
2908                 else
2909                 {
2910                         return null;
2911                 }
2912         }
2913
2914         function get_items($start = 0, $end = 0)
2915         {
2916                 if (!empty($this->multifeed_objects))
2917                 {
2918                         return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2919                 }
2920                 elseif (!isset($this->data['items']))
2921                 {
2922                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2923                         {
2924                                 $keys = array_keys($items);
2925                                 foreach ($keys as $key)
2926                                 {
2927                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2928                                 }
2929                         }
2930                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2931                         {
2932                                 $keys = array_keys($items);
2933                                 foreach ($keys as $key)
2934                                 {
2935                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2936                                 }
2937                         }
2938                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2939                         {
2940                                 $keys = array_keys($items);
2941                                 foreach ($keys as $key)
2942                                 {
2943                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2944                                 }
2945                         }
2946                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2947                         {
2948                                 $keys = array_keys($items);
2949                                 foreach ($keys as $key)
2950                                 {
2951                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2952                                 }
2953                         }
2954                         if ($items = $this->get_channel_tags('', 'item'))
2955                         {
2956                                 $keys = array_keys($items);
2957                                 foreach ($keys as $key)
2958                                 {
2959                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2960                                 }
2961                         }
2962                 }
2963
2964                 if (!empty($this->data['items']))
2965                 {
2966                         // If we want to order it by date, check if all items have a date, and then sort it
2967                         if ($this->order_by_date)
2968                         {
2969                                 if (!isset($this->data['ordered_items']))
2970                                 {
2971                                         $do_sort = true;
2972                                         foreach ($this->data['items'] as $item)
2973                                         {
2974                                                 if (!$item->get_date('U'))
2975                                                 {
2976                                                         $do_sort = false;
2977                                                         break;
2978                                                 }
2979                                         }
2980                                         $item = null;
2981                                         $this->data['ordered_items'] = $this->data['items'];
2982                                         if ($do_sort)
2983                                         {
2984                                                 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2985                                         }
2986                                 }
2987                                 $items = $this->data['ordered_items'];
2988                         }
2989                         else
2990                         {
2991                                 $items = $this->data['items'];
2992                         }
2993
2994                         // Slice the data as desired
2995                         if ($end == 0)
2996                         {
2997                                 return array_slice($items, $start);
2998                         }
2999                         else
3000                         {
3001                                 return array_slice($items, $start, $end);
3002                         }
3003                 }
3004                 else
3005                 {
3006                         return array();
3007                 }
3008         }
3009
3010         function sort_items($a, $b)
3011         {
3012                 return $a->get_date('U') <= $b->get_date('U');
3013         }
3014
3015         function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3016         {
3017                 if (is_array($urls) && sizeof($urls) > 0)
3018                 {
3019                         $items = array();
3020                         foreach ($urls as $arg)
3021                         {
3022                                 if (is_a($arg, 'SimplePie'))
3023                                 {
3024                                         $items = array_merge($items, $arg->get_items(0, $limit));
3025                                 }
3026                                 else
3027                                 {
3028                                         trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3029                                 }
3030                         }
3031
3032                         $do_sort = true;
3033                         foreach ($items as $item)
3034                         {
3035                                 if (!$item->get_date('U'))
3036                                 {
3037                                         $do_sort = false;
3038                                         break;
3039                                 }
3040                         }
3041                         $item = null;
3042                         if ($do_sort)
3043                         {
3044                                 usort($items, array('SimplePie', 'sort_items'));
3045                         }
3046
3047                         if ($end == 0)
3048                         {
3049                                 return array_slice($items, $start);
3050                         }
3051                         else
3052                         {
3053                                 return array_slice($items, $start, $end);
3054                         }
3055                 }
3056                 else
3057                 {
3058                         trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3059                         return array();
3060                 }
3061         }
3062 }
3063
3064 class SimplePie_Item
3065 {
3066         var $feed;
3067         var $data = array();
3068
3069         function SimplePie_Item($feed, $data)
3070         {
3071                 $this->feed = $feed;
3072                 $this->data = $data;
3073         }
3074
3075         function __toString()
3076         {
3077                 return md5(serialize($this->data));
3078         }
3079
3080         /**
3081          * Remove items that link back to this before destroying this object
3082          */
3083         function __destruct()
3084         {
3085                 unset($this->feed);
3086         }
3087
3088         function get_item_tags($namespace, $tag)
3089         {
3090                 if (isset($this->data['child'][$namespace][$tag]))
3091                 {
3092                         return $this->data['child'][$namespace][$tag];
3093                 }
3094                 else
3095                 {
3096                         return null;
3097                 }
3098         }
3099
3100         function get_base($element = array())
3101         {
3102                 return $this->feed->get_base($element);
3103         }
3104
3105         function sanitize($data, $type, $base = '')
3106         {
3107                 return $this->feed->sanitize($data, $type, $base);
3108         }
3109
3110         function get_feed()
3111         {
3112                 return $this->feed;
3113         }
3114
3115         function get_id($hash = false)
3116         {
3117                 if (!$hash)
3118                 {
3119                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3120                         {
3121                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122                         }
3123                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3124                         {
3125                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126                         }
3127                         elseif ($return = $this->get_item_tags('', 'guid'))
3128                         {
3129                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3130                         }
3131                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3132                         {
3133                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3134                         }
3135                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3136                         {
3137                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3138                         }
3139                         elseif (($return = $this->get_permalink()) !== null)
3140                         {
3141                                 return $return;
3142                         }
3143                         elseif (($return = $this->get_title()) !== null)
3144                         {
3145                                 return $return;
3146                         }
3147                 }
3148                 if ($this->get_permalink() !== null || $this->get_title() !== null)
3149                 {
3150                         return md5($this->get_permalink() . $this->get_title());
3151                 }
3152                 else
3153                 {
3154                         return md5(serialize($this->data));
3155                 }
3156         }
3157
3158         function get_title()
3159         {
3160                 if (!isset($this->data['title']))
3161                 {
3162                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3163                         {
3164                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3165                         }
3166                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3167                         {
3168                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3169                         }
3170                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3171                         {
3172                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3173                         }
3174                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3175                         {
3176                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3177                         }
3178                         elseif ($return = $this->get_item_tags('', 'title'))
3179                         {
3180                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3181                         }
3182                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3183                         {
3184                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3185                         }
3186                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3187                         {
3188                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3189                         }
3190                         else
3191                         {
3192                                 $this->data['title'] = null;
3193                         }
3194                 }
3195                 return $this->data['title'];
3196         }
3197
3198         function get_description($description_only = false)
3199         {
3200                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3201                 {
3202                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3203                 }
3204                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3205                 {
3206                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3207                 }
3208                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3209                 {
3210                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3211                 }
3212                 elseif ($return = $this->get_item_tags('', 'description'))
3213                 {
3214                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3215                 }
3216                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3217                 {
3218                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219                 }
3220                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3221                 {
3222                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3223                 }
3224                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3225                 {
3226                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3227                 }
3228                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3229                 {
3230                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3231                 }
3232                 elseif (!$description_only)
3233                 {
3234                         return $this->get_content(true);
3235                 }
3236                 else
3237                 {
3238                         return null;
3239                 }
3240         }
3241
3242         function get_content($content_only = false)
3243         {
3244                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3245                 {
3246                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3247                 }
3248                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3249                 {
3250                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3251                 }
3252                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3253                 {
3254                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3255                 }
3256                 elseif (!$content_only)
3257                 {
3258                         return $this->get_description(true);
3259                 }
3260                 else
3261                 {
3262                         return null;
3263                 }
3264         }
3265
3266         function get_category($key = 0)
3267         {
3268                 $categories = $this->get_categories();
3269                 if (isset($categories[$key]))
3270                 {
3271                         return $categories[$key];
3272                 }
3273                 else
3274                 {
3275                         return null;
3276                 }
3277         }
3278
3279         function get_categories()
3280         {
3281                 $categories = array();
3282
3283                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3284                 {
3285                         $term = null;
3286                         $scheme = null;
3287                         $label = null;
3288                         if (isset($category['attribs']['']['term']))
3289                         {
3290                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3291                         }
3292                         if (isset($category['attribs']['']['scheme']))
3293                         {
3294                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3295                         }
3296                         if (isset($category['attribs']['']['label']))
3297                         {
3298                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3299                         }
3300                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3301                 }
3302                 foreach ((array) $this->get_item_tags('', 'category') as $category)
3303                 {
3304                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3305                 }
3306                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3307                 {
3308                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3309                 }
3310                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3311                 {
3312                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3313                 }
3314
3315                 if (!empty($categories))
3316                 {
3317                         return SimplePie_Misc::array_unique($categories);
3318                 }
3319                 else
3320                 {
3321                         return null;
3322                 }
3323         }
3324
3325         function get_author($key = 0)
3326         {
3327                 $authors = $this->get_authors();
3328                 if (isset($authors[$key]))
3329                 {
3330                         return $authors[$key];
3331                 }
3332                 else
3333                 {
3334                         return null;
3335                 }
3336         }
3337
3338         function get_contributor($key = 0)
3339         {
3340                 $contributors = $this->get_contributors();
3341                 if (isset($contributors[$key]))
3342                 {
3343                         return $contributors[$key];
3344                 }
3345                 else
3346                 {
3347                         return null;
3348                 }
3349         }
3350
3351         function get_contributors()
3352         {
3353                 $contributors = array();
3354                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3355                 {
3356                         $name = null;
3357                         $uri = null;
3358                         $email = null;
3359                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3360                         {
3361                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3362                         }
3363                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3364                         {
3365                                 $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]));
3366                         }
3367                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3368                         {
3369                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3370                         }
3371                         if ($name !== null || $email !== null || $uri !== null)
3372                         {
3373                                 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3374                         }
3375                 }
3376                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3377                 {
3378                         $name = null;
3379                         $url = null;
3380                         $email = null;
3381                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3382                         {
3383                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3384                         }
3385                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3386                         {
3387                                 $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]));
3388                         }
3389                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3390                         {
3391                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3392                         }
3393                         if ($name !== null || $email !== null || $url !== null)
3394                         {
3395                                 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3396                         }
3397                 }
3398
3399                 if (!empty($contributors))
3400                 {
3401                         return SimplePie_Misc::array_unique($contributors);
3402                 }
3403                 else
3404                 {
3405                         return null;
3406                 }
3407         }
3408
3409         /**
3410          * @todo Atom inheritance (item author, source author, feed author)
3411          */
3412         function get_authors()
3413         {
3414                 $authors = array();
3415                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3416                 {
3417                         $name = null;
3418                         $uri = null;
3419                         $email = null;
3420                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3421                         {
3422                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3423                         }
3424                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3425                         {
3426                                 $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]));
3427                         }
3428                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3429                         {
3430                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3431                         }
3432                         if ($name !== null || $email !== null || $uri !== null)
3433                         {
3434                                 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3435                         }
3436                 }
3437                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3438                 {
3439                         $name = null;
3440                         $url = null;
3441                         $email = null;
3442                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3443                         {
3444                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3445                         }
3446                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3447                         {
3448                                 $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]));
3449                         }
3450                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3451                         {
3452                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3453                         }
3454                         if ($name !== null || $email !== null || $url !== null)
3455                         {
3456                                 $authors[] =& new $this->feed->author_class($name, $url, $email);
3457                         }
3458                 }
3459                 if ($author = $this->get_item_tags('', 'author'))
3460                 {
3461                         $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3462                 }
3463                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3464                 {
3465                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3466                 }
3467                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3468                 {
3469                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3470                 }
3471                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3472                 {
3473                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3474                 }
3475
3476                 if (!empty($authors))
3477                 {
3478                         return SimplePie_Misc::array_unique($authors);
3479                 }
3480                 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3481                 {
3482                         return $authors;
3483                 }
3484                 elseif ($authors = $this->feed->get_authors())
3485                 {
3486                         return $authors;
3487                 }
3488                 else
3489                 {
3490                         return null;
3491                 }
3492         }
3493
3494         function get_copyright()
3495         {
3496                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3497                 {
3498                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3499                 }
3500                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3501                 {
3502                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3503                 }
3504                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3505                 {
3506                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3507                 }
3508                 else
3509                 {
3510                         return null;
3511                 }
3512         }
3513
3514         function get_date($date_format = 'j F Y, g:i a')
3515         {
3516                 if (!isset($this->data['date']))
3517                 {
3518                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3519                         {
3520                                 $this->data['date']['raw'] = $return[0]['data'];
3521                         }
3522                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3523                         {
3524                                 $this->data['date']['raw'] = $return[0]['data'];
3525                         }
3526                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3527                         {
3528                                 $this->data['date']['raw'] = $return[0]['data'];
3529                         }
3530                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3531                         {
3532                                 $this->data['date']['raw'] = $return[0]['data'];
3533                         }
3534                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3535                         {
3536                                 $this->data['date']['raw'] = $return[0]['data'];
3537                         }
3538                         elseif ($return = $this->get_item_tags('', 'pubDate'))
3539                         {
3540                                 $this->data['date']['raw'] = $return[0]['data'];
3541                         }
3542                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3543                         {
3544                                 $this->data['date']['raw'] = $return[0]['data'];
3545                         }
3546                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3547                         {
3548                                 $this->data['date']['raw'] = $return[0]['data'];
3549                         }
3550
3551                         if (!empty($this->data['date']['raw']))
3552                         {
3553                                 $parser = SimplePie_Parse_Date::get();
3554                                 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3555                         }
3556                         else
3557                         {
3558                                 $this->data['date'] = null;
3559                         }
3560                 }
3561                 if ($this->data['date'])
3562                 {
3563                         $date_format = (string) $date_format;
3564                         switch ($date_format)
3565                         {
3566                                 case '':
3567                                         return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3568
3569                                 case 'U':
3570                                         return $this->data['date']['parsed'];
3571
3572                                 default:
3573                                         return date($date_format, $this->data['date']['parsed']);
3574                         }
3575                 }
3576                 else
3577                 {
3578                         return null;
3579                 }
3580         }
3581
3582         function get_local_date($date_format = '%c')
3583         {
3584                 if (!$date_format)
3585                 {
3586                         return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3587                 }
3588                 elseif (($date = $this->get_date('U')) !== null)
3589                 {
3590                         return strftime($date_format, $date);
3591                 }
3592                 else
3593                 {
3594                         return null;
3595                 }
3596         }
3597
3598         function get_permalink()
3599         {
3600                 $link = $this->get_link();
3601                 $enclosure = $this->get_enclosure(0);
3602                 if ($link !== null)
3603                 {
3604                         return $link;
3605                 }
3606                 elseif ($enclosure !== null)
3607                 {
3608                         return $enclosure->get_link();
3609                 }
3610                 else
3611                 {
3612                         return null;
3613                 }
3614         }
3615
3616         function get_link($key = 0, $rel = 'alternate')
3617         {
3618                 $links = $this->get_links($rel);
3619                 if ($links[$key] !== null)
3620                 {
3621                         return $links[$key];
3622                 }
3623                 else
3624                 {
3625                         return null;
3626                 }
3627         }
3628
3629         function get_links($rel = 'alternate')
3630         {
3631                 if (!isset($this->data['links']))
3632                 {
3633                         $this->data['links'] = array();
3634                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3635                         {
3636                                 if (isset($link['attribs']['']['href']))
3637                                 {
3638                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3639                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3640
3641                                 }
3642                         }
3643                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3644                         {
3645                                 if (isset($link['attribs']['']['href']))
3646                                 {
3647                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3648                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3649                                 }
3650                         }
3651                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3652                         {
3653                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3654                         }
3655                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3656                         {
3657                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3658                         }
3659                         if ($links = $this->get_item_tags('', 'link'))
3660                         {
3661                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3662                         }
3663                         if ($links = $this->get_item_tags('', 'guid'))
3664                         {
3665                                 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3666                                 {
3667                                         $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3668                                 }
3669                         }
3670
3671                         $keys = array_keys($this->data['links']);
3672                         foreach ($keys as $key)
3673                         {
3674                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
3675                                 {
3676                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3677                                         {
3678                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3679                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3680                                         }
3681                                         else
3682                                         {
3683                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3684                                         }
3685                                 }
3686                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3687                                 {
3688                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3689                                 }
3690                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3691                         }
3692                 }
3693                 if (isset($this->data['links'][$rel]))
3694                 {
3695                         return $this->data['links'][$rel];
3696                 }
3697                 else
3698                 {
3699                         return null;
3700                 }
3701         }
3702
3703         /**
3704          * @todo Add ability to prefer one type of content over another (in a media group).
3705          */
3706         function get_enclosure($key = 0, $prefer = null)
3707         {
3708                 $enclosures = $this->get_enclosures();
3709                 if (isset($enclosures[$key]))
3710                 {
3711                         return $enclosures[$key];
3712                 }
3713                 else
3714                 {
3715                         return null;
3716                 }
3717         }
3718
3719         /**
3720          * Grabs all available enclosures (podcasts, etc.)
3721          *
3722          * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3723          *
3724          * 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.
3725          *
3726          * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3727          * @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).
3728          */
3729         function get_enclosures()
3730         {
3731                 if (!isset($this->data['enclosures']))
3732                 {
3733                         $this->data['enclosures'] = array();
3734
3735                         // Elements
3736                         $captions_parent = null;
3737                         $categories_parent = null;
3738                         $copyrights_parent = null;
3739                         $credits_parent = null;
3740                         $description_parent = null;
3741                         $duration_parent = null;
3742                         $hashes_parent = null;
3743                         $keywords_parent = null;
3744                         $player_parent = null;
3745                         $ratings_parent = null;
3746                         $restrictions_parent = null;
3747                         $thumbnails_parent = null;
3748                         $title_parent = null;
3749
3750                         // Let's do the channel and item-level ones first, and just re-use them if we need to.
3751                         $parent = $this->get_feed();
3752
3753                         // CAPTIONS
3754                         if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3755                         {
3756                                 foreach ($captions as $caption)
3757                                 {
3758                                         $caption_type = null;
3759                                         $caption_lang = null;
3760                                         $caption_startTime = null;
3761                                         $caption_endTime = null;
3762                                         $caption_text = null;
3763                                         if (isset($caption['attribs']['']['type']))
3764                                         {
3765                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3766                                         }
3767                                         if (isset($caption['attribs']['']['lang']))
3768                                         {
3769                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3770                                         }
3771                                         if (isset($caption['attribs']['']['start']))
3772                                         {
3773                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3774                                         }
3775                                         if (isset($caption['attribs']['']['end']))
3776                                         {
3777                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3778                                         }
3779                                         if (isset($caption['data']))
3780                                         {
3781                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3782                                         }
3783                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3784                                 }
3785                         }
3786                         elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3787                         {
3788                                 foreach ($captions as $caption)
3789                                 {
3790                                         $caption_type = null;
3791                                         $caption_lang = null;
3792                                         $caption_startTime = null;
3793                                         $caption_endTime = null;
3794                                         $caption_text = null;
3795                                         if (isset($caption['attribs']['']['type']))
3796                                         {
3797                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3798                                         }
3799                                         if (isset($caption['attribs']['']['lang']))
3800                                         {
3801                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3802                                         }
3803                                         if (isset($caption['attribs']['']['start']))
3804                                         {
3805                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3806                                         }
3807                                         if (isset($caption['attribs']['']['end']))
3808                                         {
3809                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3810                                         }
3811                                         if (isset($caption['data']))
3812                                         {
3813                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3814                                         }
3815                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3816                                 }
3817                         }
3818                         if (is_array($captions_parent))
3819                         {
3820                                 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3821                         }
3822
3823                         // CATEGORIES
3824                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3825                         {
3826                                 $term = null;
3827                                 $scheme = null;
3828                                 $label = null;
3829                                 if (isset($category['data']))
3830                                 {
3831                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3832                                 }
3833                                 if (isset($category['attribs']['']['scheme']))
3834                                 {
3835                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3836                                 }
3837                                 else
3838                                 {
3839                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3840                                 }
3841                                 if (isset($category['attribs']['']['label']))
3842                                 {
3843                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3844                                 }
3845                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3846                         }
3847                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3848                         {
3849                                 $term = null;
3850                                 $scheme = null;
3851                                 $label = null;
3852                                 if (isset($category['data']))
3853                                 {
3854                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3855                                 }
3856                                 if (isset($category['attribs']['']['scheme']))
3857                                 {
3858                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3859                                 }
3860                                 else
3861                                 {
3862                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3863                                 }
3864                                 if (isset($category['attribs']['']['label']))
3865                                 {
3866                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3867                                 }
3868                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3869                         }
3870                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3871                         {
3872                                 $term = null;
3873                                 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3874                                 $label = null;
3875                                 if (isset($category['attribs']['']['text']))
3876                                 {
3877                                         $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3878                                 }
3879                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3880
3881                                 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3882                                 {
3883                                         foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3884                                         {
3885                                                 if (isset($subcategory['attribs']['']['text']))
3886                                                 {
3887                                                         $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3888                                                 }
3889                                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3890                                         }
3891                                 }
3892                         }
3893                         if (is_array($categories_parent))
3894                         {
3895                                 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3896                         }
3897
3898                         // COPYRIGHT
3899                         if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3900                         {
3901                                 $copyright_url = null;
3902                                 $copyright_label = null;
3903                                 if (isset($copyright[0]['attribs']['']['url']))
3904                                 {
3905                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3906                                 }
3907                                 if (isset($copyright[0]['data']))
3908                                 {
3909                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3910                                 }
3911                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3912                         }
3913                         elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3914                         {
3915                                 $copyright_url = null;
3916                                 $copyright_label = null;
3917                                 if (isset($copyright[0]['attribs']['']['url']))
3918                                 {
3919                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3920                                 }
3921                                 if (isset($copyright[0]['data']))
3922                                 {
3923                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3924                                 }
3925                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3926                         }
3927
3928                         // CREDITS
3929                         if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3930                         {
3931                                 foreach ($credits as $credit)
3932                                 {
3933                                         $credit_role = null;
3934                                         $credit_scheme = null;
3935                                         $credit_name = null;
3936                                         if (isset($credit['attribs']['']['role']))
3937                                         {
3938                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3939                                         }
3940                                         if (isset($credit['attribs']['']['scheme']))
3941                                         {
3942                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3943                                         }
3944                                         else
3945                                         {
3946                                                 $credit_scheme = 'urn:ebu';
3947                                         }
3948                                         if (isset($credit['data']))
3949                                         {
3950                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3951                                         }
3952                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3953                                 }
3954                         }
3955                         elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3956                         {
3957                                 foreach ($credits as $credit)
3958                                 {
3959                                         $credit_role = null;
3960                                         $credit_scheme = null;
3961                                         $credit_name = null;
3962                                         if (isset($credit['attribs']['']['role']))
3963                                         {
3964                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3965                                         }
3966                                         if (isset($credit['attribs']['']['scheme']))
3967                                         {
3968                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3969                                         }
3970                                         else
3971                                         {
3972                                                 $credit_scheme = 'urn:ebu';
3973                                         }
3974                                         if (isset($credit['data']))
3975                                         {
3976                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3977                                         }
3978                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3979                                 }
3980                         }
3981                         if (is_array($credits_parent))
3982                         {
3983                                 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3984                         }
3985
3986                         // DESCRIPTION
3987                         if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3988                         {
3989                                 if (isset($description_parent[0]['data']))
3990                                 {
3991                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3992                                 }
3993                         }
3994                         elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3995                         {
3996                                 if (isset($description_parent[0]['data']))
3997                                 {
3998                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3999                                 }
4000                         }
4001
4002                         // DURATION
4003                         if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4004                         {
4005                                 $seconds = null;
4006                                 $minutes = null;
4007                                 $hours = null;
4008                                 if (isset($duration_parent[0]['data']))
4009                                 {
4010                                         $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4011                                         if (sizeof($temp) > 0)
4012                                         {
4013                                                 (int) $seconds = array_pop($temp);
4014                                         }
4015                                         if (sizeof($temp) > 0)
4016                                         {
4017                                                 (int) $minutes = array_pop($temp);
4018                                                 $seconds += $minutes * 60;
4019                                         }
4020                                         if (sizeof($temp) > 0)
4021                                         {
4022                                                 (int) $hours = array_pop($temp);
4023                                                 $seconds += $hours * 3600;
4024                                         }
4025                                         unset($temp);
4026                                         $duration_parent = $seconds;
4027                                 }
4028                         }
4029
4030                         // HASHES
4031                         if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4032                         {
4033                                 foreach ($hashes_iterator as $hash)
4034                                 {
4035                                         $value = null;
4036                                         $algo = null;
4037                                         if (isset($hash['data']))
4038                                         {
4039                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4040                                         }
4041                                         if (isset($hash['attribs']['']['algo']))
4042                                         {
4043                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4044                                         }
4045                                         else
4046                                         {
4047                                                 $algo = 'md5';
4048                                         }
4049                                         $hashes_parent[] = $algo.':'.$value;
4050                                 }
4051                         }
4052                         elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4053                         {
4054                                 foreach ($hashes_iterator as $hash)
4055                                 {
4056                                         $value = null;
4057                                         $algo = null;
4058                                         if (isset($hash['data']))
4059                                         {
4060                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4061                                         }
4062                                         if (isset($hash['attribs']['']['algo']))
4063                                         {
4064                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4065                                         }
4066                                         else
4067                                         {
4068                                                 $algo = 'md5';
4069                                         }
4070                                         $hashes_parent[] = $algo.':'.$value;
4071                                 }
4072                         }
4073                         if (is_array($hashes_parent))
4074                         {
4075                                 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4076                         }
4077
4078                         // KEYWORDS
4079                         if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4080                         {
4081                                 if (isset($keywords[0]['data']))
4082                                 {
4083                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4084                                         foreach ($temp as $word)
4085                                         {
4086                                                 $keywords_parent[] = trim($word);
4087                                         }
4088                                 }
4089                                 unset($temp);
4090                         }
4091                         elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4092                         {
4093                                 if (isset($keywords[0]['data']))
4094                                 {
4095                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4096                                         foreach ($temp as $word)
4097                                         {
4098                                                 $keywords_parent[] = trim($word);
4099                                         }
4100                                 }
4101                                 unset($temp);
4102                         }
4103                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4104                         {
4105                                 if (isset($keywords[0]['data']))
4106                                 {
4107                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4108                                         foreach ($temp as $word)
4109                                         {
4110                                                 $keywords_parent[] = trim($word);
4111                                         }
4112                                 }
4113                                 unset($temp);
4114                         }
4115                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4116                         {
4117                                 if (isset($keywords[0]['data']))
4118                                 {
4119                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4120                                         foreach ($temp as $word)
4121                                         {
4122                                                 $keywords_parent[] = trim($word);
4123                                         }
4124                                 }
4125                                 unset($temp);
4126                         }
4127                         if (is_array($keywords_parent))
4128                         {
4129                                 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4130                         }
4131
4132                         // PLAYER
4133                         if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4134                         {
4135                                 if (isset($player_parent[0]['attribs']['']['url']))
4136                                 {
4137                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4138                                 }
4139                         }
4140                         elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4141                         {
4142                                 if (isset($player_parent[0]['attribs']['']['url']))
4143                                 {
4144                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4145                                 }
4146                         }
4147
4148                         // RATINGS
4149                         if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4150                         {
4151                                 foreach ($ratings as $rating)
4152                                 {
4153                                         $rating_scheme = null;
4154                                         $rating_value = null;
4155                                         if (isset($rating['attribs']['']['scheme']))
4156                                         {
4157                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4158                                         }
4159                                         else
4160                                         {
4161                                                 $rating_scheme = 'urn:simple';
4162                                         }
4163                                         if (isset($rating['data']))
4164                                         {
4165                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4166                                         }
4167                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4168                                 }
4169                         }
4170                         elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4171                         {
4172                                 foreach ($ratings as $rating)
4173                                 {
4174                                         $rating_scheme = 'urn:itunes';
4175                                         $rating_value = null;
4176                                         if (isset($rating['data']))
4177                                         {
4178                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4179                                         }
4180                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4181                                 }
4182                         }
4183                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4184                         {
4185                                 foreach ($ratings as $rating)
4186                                 {
4187                                         $rating_scheme = null;
4188                                         $rating_value = null;
4189                                         if (isset($rating['attribs']['']['scheme']))
4190                                         {
4191                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4192                                         }
4193                                         else
4194                                         {
4195                                                 $rating_scheme = 'urn:simple';
4196                                         }
4197                                         if (isset($rating['data']))
4198                                         {
4199                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4200                                         }
4201                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4202                                 }
4203                         }
4204                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4205                         {
4206                                 foreach ($ratings as $rating)
4207                                 {
4208                                         $rating_scheme = 'urn:itunes';
4209                                         $rating_value = null;
4210                                         if (isset($rating['data']))
4211                                         {
4212                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4213                                         }
4214                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4215                                 }
4216                         }
4217                         if (is_array($ratings_parent))
4218                         {
4219                                 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4220                         }
4221
4222                         // RESTRICTIONS
4223                         if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4224                         {
4225                                 foreach ($restrictions as $restriction)
4226                                 {
4227                                         $restriction_relationship = null;
4228                                         $restriction_type = null;
4229                                         $restriction_value = null;
4230                                         if (isset($restriction['attribs']['']['relationship']))
4231                                         {
4232                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4233                                         }
4234                                         if (isset($restriction['attribs']['']['type']))
4235                                         {
4236                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4237                                         }
4238                                         if (isset($restriction['data']))
4239                                         {
4240                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4241                                         }
4242                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4243                                 }
4244                         }
4245                         elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4246                         {
4247                                 foreach ($restrictions as $restriction)
4248                                 {
4249                                         $restriction_relationship = 'allow';
4250                                         $restriction_type = null;
4251                                         $restriction_value = 'itunes';
4252                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4253                                         {
4254                                                 $restriction_relationship = 'deny';
4255                                         }
4256                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4257                                 }
4258                         }
4259                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4260                         {
4261                                 foreach ($restrictions as $restriction)
4262                                 {
4263                                         $restriction_relationship = null;
4264                                         $restriction_type = null;
4265                                         $restriction_value = null;
4266                                         if (isset($restriction['attribs']['']['relationship']))
4267                                         {
4268                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4269                                         }
4270                                         if (isset($restriction['attribs']['']['type']))
4271                                         {
4272                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4273                                         }
4274                                         if (isset($restriction['data']))
4275                                         {
4276                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4277                                         }
4278                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4279                                 }
4280                         }
4281                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4282                         {
4283                                 foreach ($restrictions as $restriction)
4284                                 {
4285                                         $restriction_relationship = 'allow';
4286                                         $restriction_type = null;
4287                                         $restriction_value = 'itunes';
4288                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4289                                         {
4290                                                 $restriction_relationship = 'deny';
4291                                         }
4292                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4293                                 }
4294                         }
4295                         if (is_array($restrictions_parent))
4296                         {
4297                                 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4298                         }
4299
4300                         // THUMBNAILS
4301                         if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4302                         {
4303                                 foreach ($thumbnails as $thumbnail)
4304                                 {
4305                                         if (isset($thumbnail['attribs']['']['url']))
4306                                         {
4307                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4308                                         }
4309                                 }
4310                         }
4311                         elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4312                         {
4313                                 foreach ($thumbnails as $thumbnail)
4314                                 {
4315                                         if (isset($thumbnail['attribs']['']['url']))
4316                                         {
4317                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4318                                         }
4319                                 }
4320                         }
4321
4322                         // TITLES
4323                         if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4324                         {
4325                                 if (isset($title_parent[0]['data']))
4326                                 {
4327                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4328                                 }
4329                         }
4330                         elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4331                         {
4332                                 if (isset($title_parent[0]['data']))
4333                                 {
4334                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4335                                 }
4336                         }
4337
4338                         // Clear the memory
4339                         unset($parent);
4340
4341                         // Attributes
4342                         $bitrate = null;
4343                         $channels = null;
4344                         $duration = null;
4345                         $expression = null;
4346                         $framerate = null;
4347                         $height = null;
4348                         $javascript = null;
4349                         $lang = null;
4350                         $length = null;
4351                         $medium = null;
4352                         $samplingrate = null;
4353                         $type = null;
4354                         $url = null;
4355                         $width = null;
4356
4357                         // Elements
4358                         $captions = null;
4359                         $categories = null;
4360                         $copyrights = null;
4361                         $credits = null;
4362                         $description = null;
4363                         $hashes = null;
4364                         $keywords = null;
4365                         $player = null;
4366                         $ratings = null;
4367                         $restrictions = null;
4368                         $thumbnails = null;
4369                         $title = null;
4370
4371                         // If we have media:group tags, loop through them.
4372                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4373                         {
4374                                 // If we have media:content tags, loop through them.
4375                                 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4376                                 {
4377                                         if (isset($content['attribs']['']['url']))
4378                                         {
4379                                                 // Attributes
4380                                                 $bitrate = null;
4381                                                 $channels = null;
4382                                                 $duration = null;
4383                                                 $expression = null;
4384                                                 $framerate = null;
4385                                                 $height = null;
4386                                                 $javascript = null;
4387                                                 $lang = null;
4388                                                 $length = null;
4389                                                 $medium = null;
4390                                                 $samplingrate = null;
4391                                                 $type = null;
4392                                                 $url = null;
4393                                                 $width = null;
4394
4395                                                 // Elements
4396                                                 $captions = null;
4397                                                 $categories = null;
4398                                                 $copyrights = null;
4399                                                 $credits = null;
4400                                                 $description = null;
4401                                                 $hashes = null;
4402                                                 $keywords = null;
4403                                                 $player = null;
4404                                                 $ratings = null;
4405                                                 $restrictions = null;
4406                                                 $thumbnails = null;
4407                                                 $title = null;
4408
4409                                                 // Start checking the attributes of media:content
4410                                                 if (isset($content['attribs']['']['bitrate']))
4411                                                 {
4412                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4413                                                 }
4414                                                 if (isset($content['attribs']['']['channels']))
4415                                                 {
4416                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4417                                                 }
4418                                                 if (isset($content['attribs']['']['duration']))
4419                                                 {
4420                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4421                                                 }
4422                                                 else
4423                                                 {
4424                                                         $duration = $duration_parent;
4425                                                 }
4426                                                 if (isset($content['attribs']['']['expression']))
4427                                                 {
4428                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4429                                                 }
4430                                                 if (isset($content['attribs']['']['framerate']))
4431                                                 {
4432                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4433                                                 }
4434                                                 if (isset($content['attribs']['']['height']))
4435                                                 {
4436                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4437                                                 }
4438                                                 if (isset($content['attribs']['']['lang']))
4439                                                 {
4440                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4441                                                 }
4442                                                 if (isset($content['attribs']['']['fileSize']))
4443                                                 {
4444                                                         $length = ceil($content['attribs']['']['fileSize']);
4445                                                 }
4446                                                 if (isset($content['attribs']['']['medium']))
4447                                                 {
4448                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4449                                                 }
4450                                                 if (isset($content['attribs']['']['samplingrate']))
4451                                                 {
4452                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4453                                                 }
4454                                                 if (isset($content['attribs']['']['type']))
4455                                                 {
4456                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4457                                                 }
4458                                                 if (isset($content['attribs']['']['width']))
4459                                                 {
4460                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4461                                                 }
4462                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4463
4464                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4465
4466                                                 // CAPTIONS
4467                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4468                                                 {
4469                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4470                                                         {
4471                                                                 $caption_type = null;
4472                                                                 $caption_lang = null;
4473                                                                 $caption_startTime = null;
4474                                                                 $caption_endTime = null;
4475                                                                 $caption_text = null;
4476                                                                 if (isset($caption['attribs']['']['type']))
4477                                                                 {
4478                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4479                                                                 }
4480                                                                 if (isset($caption['attribs']['']['lang']))
4481                                                                 {
4482                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4483                                                                 }
4484                                                                 if (isset($caption['attribs']['']['start']))
4485                                                                 {
4486                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4487                                                                 }
4488                                                                 if (isset($caption['attribs']['']['end']))
4489                                                                 {
4490                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4491                                                                 }
4492                                                                 if (isset($caption['data']))
4493                                                                 {
4494                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4495                                                                 }
4496                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4497                                                         }
4498                                                         if (is_array($captions))
4499                                                         {
4500                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4501                                                         }
4502                                                 }
4503                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4504                                                 {
4505                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4506                                                         {
4507                                                                 $caption_type = null;
4508                                                                 $caption_lang = null;
4509                                                                 $caption_startTime = null;
4510                                                                 $caption_endTime = null;
4511                                                                 $caption_text = null;
4512                                                                 if (isset($caption['attribs']['']['type']))
4513                                                                 {
4514                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4515                                                                 }
4516                                                                 if (isset($caption['attribs']['']['lang']))
4517                                                                 {
4518                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4519                                                                 }
4520                                                                 if (isset($caption['attribs']['']['start']))
4521                                                                 {
4522                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4523                                                                 }
4524                                                                 if (isset($caption['attribs']['']['end']))
4525                                                                 {
4526                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4527                                                                 }
4528                                                                 if (isset($caption['data']))
4529                                                                 {
4530                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4531                                                                 }
4532                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4533                                                         }
4534                                                         if (is_array($captions))
4535                                                         {
4536                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4537                                                         }
4538                                                 }
4539                                                 else
4540                                                 {
4541                                                         $captions = $captions_parent;
4542                                                 }
4543
4544                                                 // CATEGORIES
4545                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4546                                                 {
4547                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4548                                                         {
4549                                                                 $term = null;
4550                                                                 $scheme = null;
4551                                                                 $label = null;
4552                                                                 if (isset($category['data']))
4553                                                                 {
4554                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4555                                                                 }
4556                                                                 if (isset($category['attribs']['']['scheme']))
4557                                                                 {
4558                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4559                                                                 }
4560                                                                 else
4561                                                                 {
4562                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4563                                                                 }
4564                                                                 if (isset($category['attribs']['']['label']))
4565                                                                 {
4566                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4567                                                                 }
4568                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4569                                                         }
4570                                                 }
4571                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4572                                                 {
4573                                                         foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4574                                                         {
4575                                                                 $term = null;
4576                                                                 $scheme = null;
4577                                                                 $label = null;
4578                                                                 if (isset($category['data']))
4579                                                                 {
4580                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4581                                                                 }
4582                                                                 if (isset($category['attribs']['']['scheme']))
4583                                                                 {
4584                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4585                                                                 }
4586                                                                 else
4587                                                                 {
4588                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4589                                                                 }
4590                                                                 if (isset($category['attribs']['']['label']))
4591                                                                 {
4592                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4593                                                                 }
4594                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4595                                                         }
4596                                                 }
4597                                                 if (is_array($categories) && is_array($categories_parent))
4598                                                 {
4599                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4600                                                 }
4601                                                 elseif (is_array($categories))
4602                                                 {
4603                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
4604                                                 }
4605                                                 elseif (is_array($categories_parent))
4606                                                 {
4607                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4608                                                 }
4609
4610                                                 // COPYRIGHTS
4611                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4612                                                 {
4613                                                         $copyright_url = null;
4614                                                         $copyright_label = null;
4615                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4616                                                         {
4617                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4618                                                         }
4619                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4620                                                         {
4621                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4622                                                         }
4623                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4624                                                 }
4625                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4626                                                 {
4627                                                         $copyright_url = null;
4628                                                         $copyright_label = null;
4629                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4630                                                         {
4631                                                                 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4632                                                         }
4633                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4634                                                         {
4635                                                                 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4636                                                         }
4637                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4638                                                 }
4639                                                 else
4640                                                 {
4641                                                         $copyrights = $copyrights_parent;
4642                                                 }
4643
4644                                                 // CREDITS
4645                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4646                                                 {
4647                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4648                                                         {
4649                                                                 $credit_role = null;
4650                                                                 $credit_scheme = null;
4651                                                                 $credit_name = null;
4652                                                                 if (isset($credit['attribs']['']['role']))
4653                                                                 {
4654                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4655                                                                 }
4656                                                                 if (isset($credit['attribs']['']['scheme']))
4657                                                                 {
4658                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4659                                                                 }
4660                                                                 else
4661                                                                 {
4662                                                                         $credit_scheme = 'urn:ebu';
4663                                                                 }
4664                                                                 if (isset($credit['data']))
4665                                                                 {
4666                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4667                                                                 }
4668                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4669                                                         }
4670                                                         if (is_array($credits))
4671                                                         {
4672                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4673                                                         }
4674                                                 }
4675                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4676                                                 {
4677                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4678                                                         {
4679                                                                 $credit_role = null;
4680                                                                 $credit_scheme = null;
4681                                                                 $credit_name = null;
4682                                                                 if (isset($credit['attribs']['']['role']))
4683                                                                 {
4684                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4685                                                                 }
4686                                                                 if (isset($credit['attribs']['']['scheme']))
4687                                                                 {
4688                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4689                                                                 }
4690                                                                 else
4691                                                                 {
4692                                                                         $credit_scheme = 'urn:ebu';
4693                                                                 }
4694                                                                 if (isset($credit['data']))
4695                                                                 {
4696                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4697                                                                 }
4698                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4699                                                         }
4700                                                         if (is_array($credits))
4701                                                         {
4702                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4703                                                         }
4704                                                 }
4705                                                 else
4706                                                 {
4707                                                         $credits = $credits_parent;
4708                                                 }
4709
4710                                                 // DESCRIPTION
4711                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4712                                                 {
4713                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4714                                                 }
4715                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4716                                                 {
4717                                                         $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4718                                                 }
4719                                                 else
4720                                                 {
4721                                                         $description = $description_parent;
4722                                                 }
4723
4724                                                 // HASHES
4725                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4726                                                 {
4727                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4728                                                         {
4729                                                                 $value = null;
4730                                                                 $algo = null;
4731                                                                 if (isset($hash['data']))
4732                                                                 {
4733                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4734                                                                 }
4735                                                                 if (isset($hash['attribs']['']['algo']))
4736                                                                 {
4737                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4738                                                                 }
4739                                                                 else
4740                                                                 {
4741                                                                         $algo = 'md5';
4742                                                                 }
4743                                                                 $hashes[] = $algo.':'.$value;
4744                                                         }
4745                                                         if (is_array($hashes))
4746                                                         {
4747                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4748                                                         }
4749                                                 }
4750                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4751                                                 {
4752                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4753                                                         {
4754                                                                 $value = null;
4755                                                                 $algo = null;
4756                                                                 if (isset($hash['data']))
4757                                                                 {
4758                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4759                                                                 }
4760                                                                 if (isset($hash['attribs']['']['algo']))
4761                                                                 {
4762                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4763                                                                 }
4764                                                                 else
4765                                                                 {
4766                                                                         $algo = 'md5';
4767                                                                 }
4768                                                                 $hashes[] = $algo.':'.$value;
4769                                                         }
4770                                                         if (is_array($hashes))
4771                                                         {
4772                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4773                                                         }
4774                                                 }
4775                                                 else
4776                                                 {
4777                                                         $hashes = $hashes_parent;
4778                                                 }
4779
4780                                                 // KEYWORDS
4781                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4782                                                 {
4783                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4784                                                         {
4785                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4786                                                                 foreach ($temp as $word)
4787                                                                 {
4788                                                                         $keywords[] = trim($word);
4789                                                                 }
4790                                                                 unset($temp);
4791                                                         }
4792                                                         if (is_array($keywords))
4793                                                         {
4794                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4795                                                         }
4796                                                 }
4797                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4798                                                 {
4799                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4800                                                         {
4801                                                                 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4802                                                                 foreach ($temp as $word)
4803                                                                 {
4804                                                                         $keywords[] = trim($word);
4805                                                                 }
4806                                                                 unset($temp);
4807                                                         }
4808                                                         if (is_array($keywords))
4809                                                         {
4810                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4811                                                         }
4812                                                 }
4813                                                 else
4814                                                 {
4815                                                         $keywords = $keywords_parent;
4816                                                 }
4817
4818                                                 // PLAYER
4819                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4820                                                 {
4821                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4822                                                 }
4823                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4824                                                 {
4825                                                         $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4826                                                 }
4827                                                 else
4828                                                 {
4829                                                         $player = $player_parent;
4830                                                 }
4831
4832                                                 // RATINGS
4833                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4834                                                 {
4835                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4836                                                         {
4837                                                                 $rating_scheme = null;
4838                                                                 $rating_value = null;
4839                                                                 if (isset($rating['attribs']['']['scheme']))
4840                                                                 {
4841                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4842                                                                 }
4843                                                                 else
4844                                                                 {
4845                                                                         $rating_scheme = 'urn:simple';
4846                                                                 }
4847                                                                 if (isset($rating['data']))
4848                                                                 {
4849                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4850                                                                 }
4851                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4852                                                         }
4853                                                         if (is_array($ratings))
4854                                                         {
4855                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4856                                                         }
4857                                                 }
4858                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4859                                                 {
4860                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4861                                                         {
4862                                                                 $rating_scheme = null;
4863                                                                 $rating_value = null;
4864                                                                 if (isset($rating['attribs']['']['scheme']))
4865                                                                 {
4866                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4867                                                                 }
4868                                                                 else
4869                                                                 {
4870                                                                         $rating_scheme = 'urn:simple';
4871                                                                 }
4872                                                                 if (isset($rating['data']))
4873                                                                 {
4874                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4875                                                                 }
4876                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4877                                                         }
4878                                                         if (is_array($ratings))
4879                                                         {
4880                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4881                                                         }
4882                                                 }
4883                                                 else
4884                                                 {
4885                                                         $ratings = $ratings_parent;
4886                                                 }
4887
4888                                                 // RESTRICTIONS
4889                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4890                                                 {
4891                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4892                                                         {
4893                                                                 $restriction_relationship = null;
4894                                                                 $restriction_type = null;
4895                                                                 $restriction_value = null;
4896                                                                 if (isset($restriction['attribs']['']['relationship']))
4897                                                                 {
4898                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4899                                                                 }
4900                                                                 if (isset($restriction['attribs']['']['type']))
4901                                                                 {
4902                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4903                                                                 }
4904                                                                 if (isset($restriction['data']))
4905                                                                 {
4906                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4907                                                                 }
4908                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4909                                                         }
4910                                                         if (is_array($restrictions))
4911                                                         {
4912                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4913                                                         }
4914                                                 }
4915                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4916                                                 {
4917                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4918                                                         {
4919                                                                 $restriction_relationship = null;
4920                                                                 $restriction_type = null;
4921                                                                 $restriction_value = null;
4922                                                                 if (isset($restriction['attribs']['']['relationship']))
4923                                                                 {
4924                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4925                                                                 }
4926                                                                 if (isset($restriction['attribs']['']['type']))
4927                                                                 {
4928                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4929                                                                 }
4930                                                                 if (isset($restriction['data']))
4931                                                                 {
4932                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4933                                                                 }
4934                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4935                                                         }
4936                                                         if (is_array($restrictions))
4937                                                         {
4938                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4939                                                         }
4940                                                 }
4941                                                 else
4942                                                 {
4943                                                         $restrictions = $restrictions_parent;
4944                                                 }
4945
4946                                                 // THUMBNAILS
4947                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4948                                                 {
4949                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4950                                                         {
4951                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4952                                                         }
4953                                                         if (is_array($thumbnails))
4954                                                         {
4955                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4956                                                         }
4957                                                 }
4958                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4959                                                 {
4960                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4961                                                         {
4962                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4963                                                         }
4964                                                         if (is_array($thumbnails))
4965                                                         {
4966                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4967                                                         }
4968                                                 }
4969                                                 else
4970                                                 {
4971                                                         $thumbnails = $thumbnails_parent;
4972                                                 }
4973
4974                                                 // TITLES
4975                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4976                                                 {
4977                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4978                                                 }
4979                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4980                                                 {
4981                                                         $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4982                                                 }
4983                                                 else
4984                                                 {
4985                                                         $title = $title_parent;
4986                                                 }
4987
4988                                                 $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);
4989                                         }
4990                                 }
4991                         }
4992
4993                         // If we have standalone media:content tags, loop through them.
4994                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4995                         {
4996                                 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4997                                 {
4998                                         if (isset($content['attribs']['']['url']))
4999                                         {
5000                                                 // Attributes
5001                                                 $bitrate = null;
5002                                                 $channels = null;
5003                                                 $duration = null;
5004                                                 $expression = null;
5005                                                 $framerate = null;
5006                                                 $height = null;
5007                                                 $javascript = null;
5008                                                 $lang = null;
5009                                                 $length = null;
5010                                                 $medium = null;
5011                                                 $samplingrate = null;
5012                                                 $type = null;
5013                                                 $url = null;
5014                                                 $width = null;
5015
5016                                                 // Elements
5017                                                 $captions = null;
5018                                                 $categories = null;
5019                                                 $copyrights = null;
5020                                                 $credits = null;
5021                                                 $description = null;
5022                                                 $hashes = null;
5023                                                 $keywords = null;
5024                                                 $player = null;
5025                                                 $ratings = null;
5026                                                 $restrictions = null;
5027                                                 $thumbnails = null;
5028                                                 $title = null;
5029
5030                                                 // Start checking the attributes of media:content
5031                                                 if (isset($content['attribs']['']['bitrate']))
5032                                                 {
5033                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5034                                                 }
5035                                                 if (isset($content['attribs']['']['channels']))
5036                                                 {
5037                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5038                                                 }
5039                                                 if (isset($content['attribs']['']['duration']))
5040                                                 {
5041                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5042                                                 }
5043                                                 else
5044                                                 {
5045                                                         $duration = $duration_parent;
5046                                                 }
5047                                                 if (isset($content['attribs']['']['expression']))
5048                                                 {
5049                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5050                                                 }
5051                                                 if (isset($content['attribs']['']['framerate']))
5052                                                 {
5053                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5054                                                 }
5055                                                 if (isset($content['attribs']['']['height']))
5056                                                 {
5057                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5058                                                 }
5059                                                 if (isset($content['attribs']['']['lang']))
5060                                                 {
5061                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5062                                                 }
5063                                                 if (isset($content['attribs']['']['fileSize']))
5064                                                 {
5065                                                         $length = ceil($content['attribs']['']['fileSize']);
5066                                                 }
5067                                                 if (isset($content['attribs']['']['medium']))
5068                                                 {
5069                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5070                                                 }
5071                                                 if (isset($content['attribs']['']['samplingrate']))
5072                                                 {
5073                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5074                                                 }
5075                                                 if (isset($content['attribs']['']['type']))
5076                                                 {
5077                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5078                                                 }
5079                                                 if (isset($content['attribs']['']['width']))
5080                                                 {
5081                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5082                                                 }
5083                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5084
5085                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5086
5087                                                 // CAPTIONS
5088                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5089                                                 {
5090                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5091                                                         {
5092                                                                 $caption_type = null;
5093                                                                 $caption_lang = null;
5094                                                                 $caption_startTime = null;
5095                                                                 $caption_endTime = null;
5096                                                                 $caption_text = null;
5097                                                                 if (isset($caption['attribs']['']['type']))
5098                                                                 {
5099                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5100                                                                 }
5101                                                                 if (isset($caption['attribs']['']['lang']))
5102                                                                 {
5103                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5104                                                                 }
5105                                                                 if (isset($caption['attribs']['']['start']))
5106                                                                 {
5107                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5108                                                                 }
5109                                                                 if (isset($caption['attribs']['']['end']))
5110                                                                 {
5111                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5112                                                                 }
5113                                                                 if (isset($caption['data']))
5114                                                                 {
5115                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5116                                                                 }
5117                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5118                                                         }
5119                                                         if (is_array($captions))
5120                                                         {
5121                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
5122                                                         }
5123                                                 }
5124                                                 else
5125                                                 {
5126                                                         $captions = $captions_parent;
5127                                                 }
5128
5129                                                 // CATEGORIES
5130                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5131                                                 {
5132                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5133                                                         {
5134                                                                 $term = null;
5135                                                                 $scheme = null;
5136                                                                 $label = null;
5137                                                                 if (isset($category['data']))
5138                                                                 {
5139                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5140                                                                 }
5141                                                                 if (isset($category['attribs']['']['scheme']))
5142                                                                 {
5143                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5144                                                                 }
5145                                                                 else
5146                                                                 {
5147                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
5148                                                                 }
5149                                                                 if (isset($category['attribs']['']['label']))
5150                                                                 {
5151                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5152                                                                 }
5153                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5154                                                         }
5155                                                 }
5156                                                 if (is_array($categories) && is_array($categories_parent))
5157                                                 {
5158                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5159                                                 }
5160                                                 elseif (is_array($categories))
5161                                                 {
5162                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
5163                                                 }
5164                                                 elseif (is_array($categories_parent))
5165                                                 {
5166                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5167                                                 }
5168                                                 else
5169                                                 {
5170                                                         $categories = null;
5171                                                 }
5172
5173                                                 // COPYRIGHTS
5174                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5175                                                 {
5176                                                         $copyright_url = null;
5177                                                         $copyright_label = null;
5178                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5179                                                         {
5180                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5181                                                         }
5182                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5183                                                         {
5184                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5185                                                         }
5186                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5187                                                 }
5188                                                 else
5189                                                 {
5190                                                         $copyrights = $copyrights_parent;
5191                                                 }
5192
5193                                                 // CREDITS
5194                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5195                                                 {
5196                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5197                                                         {
5198                                                                 $credit_role = null;
5199                                                                 $credit_scheme = null;
5200                                                                 $credit_name = null;
5201                                                                 if (isset($credit['attribs']['']['role']))
5202                                                                 {
5203                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5204                                                                 }
5205                                                                 if (isset($credit['attribs']['']['scheme']))
5206                                                                 {
5207                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5208                                                                 }
5209                                                                 else
5210                                                                 {
5211                                                                         $credit_scheme = 'urn:ebu';
5212                                                                 }
5213                                                                 if (isset($credit['data']))
5214                                                                 {
5215                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5216                                                                 }
5217                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5218                                                         }
5219                                                         if (is_array($credits))
5220                                                         {
5221                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
5222                                                         }
5223                                                 }
5224                                                 else
5225                                                 {
5226                                                         $credits = $credits_parent;
5227                                                 }
5228
5229                                                 // DESCRIPTION
5230                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5231                                                 {
5232                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5233                                                 }
5234                                                 else
5235                                                 {
5236                                                         $description = $description_parent;
5237                                                 }
5238
5239                                                 // HASHES
5240                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5241                                                 {
5242                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5243                                                         {
5244                                                                 $value = null;
5245                                                                 $algo = null;
5246                                                                 if (isset($hash['data']))
5247                                                                 {
5248                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5249                                                                 }
5250                                                                 if (isset($hash['attribs']['']['algo']))
5251                                                                 {
5252                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5253                                                                 }
5254                                                                 else
5255                                                                 {
5256                                                                         $algo = 'md5';
5257                                                                 }
5258                                                                 $hashes[] = $algo.':'.$value;
5259                                                         }
5260                                                         if (is_array($hashes))
5261                                                         {
5262                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5263                                                         }
5264                                                 }
5265                                                 else
5266                                                 {
5267                                                         $hashes = $hashes_parent;
5268                                                 }
5269
5270                                                 // KEYWORDS
5271                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5272                                                 {
5273                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5274                                                         {
5275                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5276                                                                 foreach ($temp as $word)
5277                                                                 {
5278                                                                         $keywords[] = trim($word);
5279                                                                 }
5280                                                                 unset($temp);
5281                                                         }
5282                                                         if (is_array($keywords))
5283                                                         {
5284                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5285                                                         }
5286                                                 }
5287                                                 else
5288                                                 {
5289                                                         $keywords = $keywords_parent;
5290                                                 }
5291
5292                                                 // PLAYER
5293                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5294                                                 {
5295                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5296                                                 }
5297                                                 else
5298                                                 {
5299                                                         $player = $player_parent;
5300                                                 }
5301
5302                                                 // RATINGS
5303                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5304                                                 {
5305                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5306                                                         {
5307                                                                 $rating_scheme = null;
5308                                                                 $rating_value = null;
5309                                                                 if (isset($rating['attribs']['']['scheme']))
5310                                                                 {
5311                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5312                                                                 }
5313                                                                 else
5314                                                                 {
5315                                                                         $rating_scheme = 'urn:simple';
5316                                                                 }
5317                                                                 if (isset($rating['data']))
5318                                                                 {
5319                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5320                                                                 }
5321                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5322                                                         }
5323                                                         if (is_array($ratings))
5324                                                         {
5325                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5326                                                         }
5327                                                 }
5328                                                 else
5329                                                 {
5330                                                         $ratings = $ratings_parent;
5331                                                 }
5332
5333                                                 // RESTRICTIONS
5334                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5335                                                 {
5336                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5337                                                         {
5338                                                                 $restriction_relationship = null;
5339                                                                 $restriction_type = null;
5340                                                                 $restriction_value = null;
5341                                                                 if (isset($restriction['attribs']['']['relationship']))
5342                                                                 {
5343                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5344                                                                 }
5345                                                                 if (isset($restriction['attribs']['']['type']))
5346                                                                 {
5347                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5348                                                                 }
5349                                                                 if (isset($restriction['data']))
5350                                                                 {
5351                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5352                                                                 }
5353                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5354                                                         }
5355                                                         if (is_array($restrictions))
5356                                                         {
5357                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5358                                                         }
5359                                                 }
5360                                                 else
5361                                                 {
5362                                                         $restrictions = $restrictions_parent;
5363                                                 }
5364
5365                                                 // THUMBNAILS
5366                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5367                                                 {
5368                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5369                                                         {
5370                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5371                                                         }
5372                                                         if (is_array($thumbnails))
5373                                                         {
5374                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5375                                                         }
5376                                                 }
5377                                                 else
5378                                                 {
5379                                                         $thumbnails = $thumbnails_parent;
5380                                                 }
5381
5382                                                 // TITLES
5383                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5384                                                 {
5385                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5386                                                 }
5387                                                 else
5388                                                 {
5389                                                         $title = $title_parent;
5390                                                 }
5391
5392                                                 $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);
5393                                         }
5394                                 }
5395                         }
5396
5397                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5398                         {
5399                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5400                                 {
5401                                         // Attributes
5402                                         $bitrate = null;
5403                                         $channels = null;
5404                                         $duration = null;
5405                                         $expression = null;
5406                                         $framerate = null;
5407                                         $height = null;
5408                                         $javascript = null;
5409                                         $lang = null;
5410                                         $length = null;
5411                                         $medium = null;
5412                                         $samplingrate = null;
5413                                         $type = null;
5414                                         $url = null;
5415                                         $width = null;
5416
5417                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5418                                         if (isset($link['attribs']['']['type']))
5419                                         {
5420                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5421                                         }
5422                                         if (isset($link['attribs']['']['length']))
5423                                         {
5424                                                 $length = ceil($link['attribs']['']['length']);
5425                                         }
5426
5427                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5428                                         $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);
5429                                 }
5430                         }
5431
5432                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5433                         {
5434                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5435                                 {
5436                                         // Attributes
5437                                         $bitrate = null;
5438                                         $channels = null;
5439                                         $duration = null;
5440                                         $expression = null;
5441                                         $framerate = null;
5442                                         $height = null;
5443                                         $javascript = null;
5444                                         $lang = null;
5445                                         $length = null;
5446                                         $medium = null;
5447                                         $samplingrate = null;
5448                                         $type = null;
5449                                         $url = null;
5450                                         $width = null;
5451
5452                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5453                                         if (isset($link['attribs']['']['type']))
5454                                         {
5455                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5456                                         }
5457                                         if (isset($link['attribs']['']['length']))
5458                                         {
5459                                                 $length = ceil($link['attribs']['']['length']);
5460                                         }
5461
5462                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5463                                         $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);
5464                                 }
5465                         }
5466
5467                         if ($enclosure = $this->get_item_tags('', 'enclosure'))
5468                         {
5469                                 if (isset($enclosure[0]['attribs']['']['url']))
5470                                 {
5471                                         // Attributes
5472                                         $bitrate = null;
5473                                         $channels = null;
5474                                         $duration = null;
5475                                         $expression = null;
5476                                         $framerate = null;
5477                                         $height = null;
5478                                         $javascript = null;
5479                                         $lang = null;
5480                                         $length = null;
5481                                         $medium = null;
5482                                         $samplingrate = null;
5483                                         $type = null;
5484                                         $url = null;
5485                                         $width = null;
5486
5487                                         $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5488                                         if (isset($enclosure[0]['attribs']['']['type']))
5489                                         {
5490                                                 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5491                                         }
5492                                         if (isset($enclosure[0]['attribs']['']['length']))
5493                                         {
5494                                                 $length = ceil($enclosure[0]['attribs']['']['length']);
5495                                         }
5496
5497                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5498                                         $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);
5499                                 }
5500                         }
5501
5502                         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))
5503                         {
5504                                 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5505                                 $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);
5506                         }
5507
5508                         $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5509                 }
5510                 if (!empty($this->data['enclosures']))
5511                 {
5512                         return $this->data['enclosures'];
5513                 }
5514                 else
5515                 {
5516                         return null;
5517                 }
5518         }
5519
5520         function get_latitude()
5521         {
5522                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5523                 {
5524                         return (float) $return[0]['data'];
5525                 }
5526                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5527                 {
5528                         return (float) $match[1];
5529                 }
5530                 else
5531                 {
5532                         return null;
5533                 }
5534         }
5535
5536         function get_longitude()
5537         {
5538                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5539                 {
5540                         return (float) $return[0]['data'];
5541                 }
5542                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5543                 {
5544                         return (float) $return[0]['data'];
5545                 }
5546                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5547                 {
5548                         return (float) $match[2];
5549                 }
5550                 else
5551                 {
5552                         return null;
5553                 }
5554         }
5555
5556         function get_source()
5557         {
5558                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5559                 {
5560                         return new $this->feed->source_class($this, $return[0]);
5561                 }
5562                 else
5563                 {
5564                         return null;
5565                 }
5566         }
5567
5568         /**
5569          * Creates the add_to_* methods' return data
5570          *
5571          * @access private
5572          * @param string $item_url String to prefix to the item permalink
5573          * @param string $title_url String to prefix to the item title
5574          * (and suffix to the item permalink)
5575          * @return mixed URL if feed exists, false otherwise
5576          */
5577         function add_to_service($item_url, $title_url = null, $summary_url = null)
5578         {
5579                 if ($this->get_permalink() !== null)
5580                 {
5581                         $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5582                         if ($title_url !== null && $this->get_title() !== null)
5583                         {
5584                                 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5585                         }
5586                         if ($summary_url !== null && $this->get_description() !== null)
5587                         {
5588                                 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5589                         }
5590                         return $return;
5591                 }
5592                 else
5593                 {
5594                         return null;
5595                 }
5596         }
5597
5598         function add_to_blinklist()
5599         {
5600                 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5601         }
5602
5603         function add_to_blogmarks()
5604         {
5605                 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5606         }
5607
5608         function add_to_delicious()
5609         {
5610                 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5611         }
5612
5613         function add_to_digg()
5614         {
5615                 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5616         }
5617
5618         function add_to_furl()
5619         {
5620                 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5621         }
5622
5623         function add_to_magnolia()
5624         {
5625                 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5626         }
5627
5628         function add_to_myweb20()
5629         {
5630                 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5631         }
5632
5633         function add_to_newsvine()
5634         {
5635                 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5636         }
5637
5638         function add_to_reddit()
5639         {
5640                 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5641         }
5642
5643         function add_to_segnalo()
5644         {
5645                 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5646         }
5647
5648         function add_to_simpy()
5649         {
5650                 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5651         }
5652
5653         function add_to_spurl()
5654         {
5655                 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5656         }
5657
5658         function add_to_wists()
5659         {
5660                 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5661         }
5662
5663         function search_technorati()
5664         {
5665                 return $this->add_to_service('http://www.technorati.com/search/');
5666         }
5667 }
5668
5669 class SimplePie_Source
5670 {
5671         var $item;
5672         var $data = array();
5673
5674         function SimplePie_Source($item, $data)
5675         {
5676                 $this->item = $item;
5677                 $this->data = $data;
5678         }
5679
5680         function __toString()
5681         {
5682                 return md5(serialize($this->data));
5683         }
5684
5685         /**
5686          * Remove items that link back to this before destroying this object
5687          */
5688         function __destruct()
5689         {
5690                 unset($this->item);
5691         }
5692
5693         function get_source_tags($namespace, $tag)
5694         {
5695                 if (isset($this->data['child'][$namespace][$tag]))
5696                 {
5697                         return $this->data['child'][$namespace][$tag];
5698                 }
5699                 else
5700                 {
5701                         return null;
5702                 }
5703         }
5704
5705         function get_base($element = array())
5706         {
5707                 return $this->item->get_base($element);
5708         }
5709
5710         function sanitize($data, $type, $base = '')
5711         {
5712                 return $this->item->sanitize($data, $type, $base);
5713         }
5714
5715         function get_item()
5716         {
5717                 return $this->item;
5718         }
5719
5720         function get_title()
5721         {
5722                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5723                 {
5724                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5725                 }
5726                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5727                 {
5728                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5729                 }
5730                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5731                 {
5732                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5733                 }
5734                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5735                 {
5736                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5737                 }
5738                 elseif ($return = $this->get_source_tags('', 'title'))
5739                 {
5740                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5741                 }
5742                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5743                 {
5744                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5745                 }
5746                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5747                 {
5748                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5749                 }
5750                 else
5751                 {
5752                         return null;
5753                 }
5754         }
5755
5756         function get_category($key = 0)
5757         {
5758                 $categories = $this->get_categories();
5759                 if (isset($categories[$key]))
5760                 {
5761                         return $categories[$key];
5762                 }
5763                 else
5764                 {
5765                         return null;
5766                 }
5767         }
5768
5769         function get_categories()
5770         {
5771                 $categories = array();
5772
5773                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5774                 {
5775                         $term = null;
5776                         $scheme = null;
5777                         $label = null;
5778                         if (isset($category['attribs']['']['term']))
5779                         {
5780                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5781                         }
5782                         if (isset($category['attribs']['']['scheme']))
5783                         {
5784                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5785                         }
5786                         if (isset($category['attribs']['']['label']))
5787                         {
5788                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5789                         }
5790                         $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5791                 }
5792                 foreach ((array) $this->get_source_tags('', 'category') as $category)
5793                 {
5794                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5795                 }
5796                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5797                 {
5798                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5799                 }
5800                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5801                 {
5802                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5803                 }
5804
5805                 if (!empty($categories))
5806                 {
5807                         return SimplePie_Misc::array_unique($categories);
5808                 }
5809                 else
5810                 {
5811                         return null;
5812                 }
5813         }
5814
5815         function get_author($key = 0)
5816         {
5817                 $authors = $this->get_authors();
5818                 if (isset($authors[$key]))
5819                 {
5820                         return $authors[$key];
5821                 }
5822                 else
5823                 {
5824                         return null;
5825                 }
5826         }
5827
5828         function get_authors()
5829         {
5830                 $authors = array();
5831                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5832                 {
5833                         $name = null;
5834                         $uri = null;
5835                         $email = null;
5836                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5837                         {
5838                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5839                         }
5840                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5841                         {
5842                                 $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]));
5843                         }
5844                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5845                         {
5846                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5847                         }
5848                         if ($name !== null || $email !== null || $uri !== null)
5849                         {
5850                                 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5851                         }
5852                 }
5853                 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5854                 {
5855                         $name = null;
5856                         $url = null;
5857                         $email = null;
5858                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5859                         {
5860                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5861                         }
5862                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5863                         {
5864                                 $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]));
5865                         }
5866                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5867                         {
5868                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5869                         }
5870                         if ($name !== null || $email !== null || $url !== null)
5871                         {
5872                                 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5873                         }
5874                 }
5875                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5876                 {
5877                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5878                 }
5879                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5880                 {
5881                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5882                 }
5883                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5884                 {
5885                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5886                 }
5887
5888                 if (!empty($authors))
5889                 {
5890                         return SimplePie_Misc::array_unique($authors);
5891                 }
5892                 else
5893                 {
5894                         return null;
5895                 }
5896         }
5897
5898         function get_contributor($key = 0)
5899         {
5900                 $contributors = $this->get_contributors();
5901                 if (isset($contributors[$key]))
5902                 {
5903                         return $contributors[$key];
5904                 }
5905                 else
5906                 {
5907                         return null;
5908                 }
5909         }
5910
5911         function get_contributors()
5912         {
5913                 $contributors = array();
5914                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5915                 {
5916                         $name = null;
5917                         $uri = null;
5918                         $email = null;
5919                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5920                         {
5921                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5922                         }
5923                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5924                         {
5925                                 $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]));
5926                         }
5927                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5928                         {
5929                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5930                         }
5931                         if ($name !== null || $email !== null || $uri !== null)
5932                         {
5933                                 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5934                         }
5935                 }
5936                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5937                 {
5938                         $name = null;
5939                         $url = null;
5940                         $email = null;
5941                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5942                         {
5943                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5944                         }
5945                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5946                         {
5947                                 $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]));
5948                         }
5949                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5950                         {
5951                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5952                         }
5953                         if ($name !== null || $email !== null || $url !== null)
5954                         {
5955                                 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5956                         }
5957                 }
5958
5959                 if (!empty($contributors))
5960                 {
5961                         return SimplePie_Misc::array_unique($contributors);
5962                 }
5963                 else
5964                 {
5965                         return null;
5966                 }
5967         }
5968
5969         function get_link($key = 0, $rel = 'alternate')
5970         {
5971                 $links = $this->get_links($rel);
5972                 if (isset($links[$key]))
5973                 {
5974                         return $links[$key];
5975                 }
5976                 else
5977                 {
5978                         return null;
5979                 }
5980         }
5981
5982         /**
5983          * Added for parity between the parent-level and the item/entry-level.
5984          */
5985         function get_permalink()
5986         {
5987                 return $this->get_link(0);
5988         }
5989
5990         function get_links($rel = 'alternate')
5991         {
5992                 if (!isset($this->data['links']))
5993                 {
5994                         $this->data['links'] = array();
5995                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5996                         {
5997                                 foreach ($links as $link)
5998                                 {
5999                                         if (isset($link['attribs']['']['href']))
6000                                         {
6001                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6002                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6003                                         }
6004                                 }
6005                         }
6006                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6007                         {
6008                                 foreach ($links as $link)
6009                                 {
6010                                         if (isset($link['attribs']['']['href']))
6011                                         {
6012                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6013                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6014
6015                                         }
6016                                 }
6017                         }
6018                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6019                         {
6020                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6021                         }
6022                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6023                         {
6024                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6025                         }
6026                         if ($links = $this->get_source_tags('', 'link'))
6027                         {
6028                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6029                         }
6030
6031                         $keys = array_keys($this->data['links']);
6032                         foreach ($keys as $key)
6033                         {
6034                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
6035                                 {
6036                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6037                                         {
6038                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6039                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6040                                         }
6041                                         else
6042                                         {
6043                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6044                                         }
6045                                 }
6046                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6047                                 {
6048                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6049                                 }
6050                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6051                         }
6052                 }
6053
6054                 if (isset($this->data['links'][$rel]))
6055                 {
6056                         return $this->data['links'][$rel];
6057                 }
6058                 else
6059                 {
6060                         return null;
6061                 }
6062         }
6063
6064         function get_description()
6065         {
6066                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6067                 {
6068                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6069                 }
6070                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6071                 {
6072                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6073                 }
6074                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6075                 {
6076                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6077                 }
6078                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6079                 {
6080                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6081                 }
6082                 elseif ($return = $this->get_source_tags('', 'description'))
6083                 {
6084                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6085                 }
6086                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6087                 {
6088                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6089                 }
6090                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6091                 {
6092                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6093                 }
6094                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6095                 {
6096                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6097                 }
6098                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6099                 {
6100                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6101                 }
6102                 else
6103                 {
6104                         return null;
6105                 }
6106         }
6107
6108         function get_copyright()
6109         {
6110                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6111                 {
6112                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6113                 }
6114                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6115                 {
6116                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6117                 }
6118                 elseif ($return = $this->get_source_tags('', 'copyright'))
6119                 {
6120                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6121                 }
6122                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6123                 {
6124                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6125                 }
6126                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6127                 {
6128                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6129                 }
6130                 else
6131                 {
6132                         return null;
6133                 }
6134         }
6135
6136         function get_language()
6137         {
6138                 if ($return = $this->get_source_tags('', 'language'))
6139                 {
6140                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6141                 }
6142                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6143                 {
6144                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6145                 }
6146                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6147                 {
6148                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6149                 }
6150                 elseif (isset($this->data['xml_lang']))
6151                 {
6152                         return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6153                 }
6154                 else
6155                 {
6156                         return null;
6157                 }
6158         }
6159
6160         function get_latitude()
6161         {
6162                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6163                 {
6164                         return (float) $return[0]['data'];
6165                 }
6166                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6167                 {
6168                         return (float) $match[1];
6169                 }
6170                 else
6171                 {
6172                         return null;
6173                 }
6174         }
6175
6176         function get_longitude()
6177         {
6178                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6179                 {
6180                         return (float) $return[0]['data'];
6181                 }
6182                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6183                 {
6184                         return (float) $return[0]['data'];
6185                 }
6186                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6187                 {
6188                         return (float) $match[2];
6189                 }
6190                 else
6191                 {
6192                         return null;
6193                 }
6194         }
6195
6196         function get_image_url()
6197         {
6198                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6199                 {
6200                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6201                 }
6202                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6203                 {
6204                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6205                 }
6206                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6207                 {
6208                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6209                 }
6210                 else
6211                 {
6212                         return null;
6213                 }
6214         }
6215 }
6216
6217 class SimplePie_Author
6218 {
6219         var $name;
6220         var $link;
6221         var $email;
6222
6223         // Constructor, used to input the data
6224         function SimplePie_Author($name = null, $link = null, $email = null)
6225         {
6226                 $this->name = $name;
6227                 $this->link = $link;
6228                 $this->email = $email;
6229         }
6230
6231         function __toString()
6232         {
6233                 // There is no $this->data here
6234                 return md5(serialize($this));
6235         }
6236
6237         function get_name()
6238         {
6239                 if ($this->name !== null)
6240                 {
6241                         return $this->name;
6242                 }
6243                 else
6244                 {
6245                         return null;
6246                 }
6247         }
6248
6249         function get_link()
6250         {
6251                 if ($this->link !== null)
6252                 {
6253                         return $this->link;
6254                 }
6255                 else
6256                 {
6257                         return null;
6258                 }
6259         }
6260
6261         function get_email()
6262         {
6263                 if ($this->email !== null)
6264                 {
6265                         return $this->email;
6266                 }
6267                 else
6268                 {
6269                         return null;
6270                 }
6271         }
6272 }
6273
6274 class SimplePie_Category
6275 {
6276         var $term;
6277         var $scheme;
6278         var $label;
6279
6280         // Constructor, used to input the data
6281         function SimplePie_Category($term = null, $scheme = null, $label = null)
6282         {
6283                 $this->term = $term;
6284                 $this->scheme = $scheme;
6285                 $this->label = $label;
6286         }
6287
6288         function __toString()
6289         {
6290                 // There is no $this->data here
6291                 return md5(serialize($this));
6292         }
6293
6294         function get_term()
6295         {
6296                 if ($this->term !== null)
6297                 {
6298                         return $this->term;
6299                 }
6300                 else
6301                 {
6302                         return null;
6303                 }
6304         }
6305
6306         function get_scheme()
6307         {
6308                 if ($this->scheme !== null)
6309                 {
6310                         return $this->scheme;
6311                 }
6312                 else
6313                 {
6314                         return null;
6315                 }
6316         }
6317
6318         function get_label()
6319         {
6320                 if ($this->label !== null)
6321                 {
6322                         return $this->label;
6323                 }
6324                 else
6325                 {
6326                         return $this->get_term();
6327                 }
6328         }
6329 }
6330
6331 class SimplePie_Enclosure
6332 {
6333         var $bitrate;
6334         var $captions;
6335         var $categories;
6336         var $channels;
6337         var $copyright;
6338         var $credits;
6339         var $description;
6340         var $duration;
6341         var $expression;
6342         var $framerate;
6343         var $handler;
6344         var $hashes;
6345         var $height;
6346         var $javascript;
6347         var $keywords;
6348         var $lang;
6349         var $length;
6350         var $link;
6351         var $medium;
6352         var $player;
6353         var $ratings;
6354         var $restrictions;
6355         var $samplingrate;
6356         var $thumbnails;
6357         var $title;
6358         var $type;
6359         var $width;
6360
6361         // Constructor, used to input the data
6362         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)
6363         {
6364                 $this->bitrate = $bitrate;
6365                 $this->captions = $captions;
6366                 $this->categories = $categories;
6367                 $this->channels = $channels;
6368                 $this->copyright = $copyright;
6369                 $this->credits = $credits;
6370                 $this->description = $description;
6371                 $this->duration = $duration;
6372                 $this->expression = $expression;
6373                 $this->framerate = $framerate;
6374                 $this->hashes = $hashes;
6375                 $this->height = $height;
6376                 $this->javascript = $javascript;
6377                 $this->keywords = $keywords;
6378                 $this->lang = $lang;
6379                 $this->length = $length;
6380                 $this->link = $link;
6381                 $this->medium = $medium;
6382                 $this->player = $player;
6383                 $this->ratings = $ratings;
6384                 $this->restrictions = $restrictions;
6385                 $this->samplingrate = $samplingrate;
6386                 $this->thumbnails = $thumbnails;
6387                 $this->title = $title;
6388                 $this->type = $type;
6389                 $this->width = $width;
6390                 if (class_exists('idna_convert'))
6391                 {
6392                         $idn =& new idna_convert;
6393                         $parsed = SimplePie_Misc::parse_url($link);
6394                         $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6395                 }
6396                 $this->handler = $this->get_handler(); // Needs to load last
6397         }
6398
6399         function __toString()
6400         {
6401                 // There is no $this->data here
6402                 return md5(serialize($this));
6403         }
6404
6405         function get_bitrate()
6406         {
6407                 if ($this->bitrate !== null)
6408                 {
6409                         return $this->bitrate;
6410                 }
6411                 else
6412                 {
6413                         return null;
6414                 }
6415         }
6416
6417         function get_caption($key = 0)
6418         {
6419                 $captions = $this->get_captions();
6420                 if (isset($captions[$key]))
6421                 {
6422                         return $captions[$key];
6423                 }
6424                 else
6425                 {
6426                         return null;
6427                 }
6428         }
6429
6430         function get_captions()
6431         {
6432                 if ($this->captions !== null)
6433                 {
6434                         return $this->captions;
6435                 }
6436                 else
6437                 {
6438                         return null;
6439                 }
6440         }
6441
6442         function get_category($key = 0)
6443         {
6444                 $categories = $this->get_categories();
6445                 if (isset($categories[$key]))
6446                 {
6447                         return $categories[$key];
6448                 }
6449                 else
6450                 {
6451                         return null;
6452                 }
6453         }
6454
6455         function get_categories()
6456         {
6457                 if ($this->categories !== null)
6458                 {
6459                         return $this->categories;
6460                 }
6461                 else
6462                 {
6463                         return null;
6464                 }
6465         }
6466
6467         function get_channels()
6468         {
6469                 if ($this->channels !== null)
6470                 {
6471                         return $this->channels;
6472                 }
6473                 else
6474                 {
6475                         return null;
6476                 }
6477         }
6478
6479         function get_copyright()
6480         {
6481                 if ($this->copyright !== null)
6482                 {
6483                         return $this->copyright;
6484                 }
6485                 else
6486                 {
6487                         return null;
6488                 }
6489         }
6490
6491         function get_credit($key = 0)
6492         {
6493                 $credits = $this->get_credits();
6494                 if (isset($credits[$key]))
6495                 {
6496                         return $credits[$key];
6497                 }
6498                 else
6499                 {
6500                         return null;
6501                 }
6502         }
6503
6504         function get_credits()
6505         {
6506                 if ($this->credits !== null)
6507                 {
6508                         return $this->credits;
6509                 }
6510                 else
6511                 {
6512                         return null;
6513                 }
6514         }
6515
6516         function get_description()
6517         {
6518                 if ($this->description !== null)
6519                 {
6520                         return $this->description;
6521                 }
6522                 else
6523                 {
6524                         return null;
6525                 }
6526         }
6527
6528         function get_duration($convert = false)
6529         {
6530                 if ($this->duration !== null)
6531                 {
6532                         if ($convert)
6533                         {
6534                                 $time = SimplePie_Misc::time_hms($this->duration);
6535                                 return $time;
6536                         }
6537                         else
6538                         {
6539                                 return $this->duration;
6540                         }
6541                 }
6542                 else
6543                 {
6544                         return null;
6545                 }
6546         }
6547
6548         function get_expression()
6549         {
6550                 if ($this->expression !== null)
6551                 {
6552                         return $this->expression;
6553                 }
6554                 else
6555                 {
6556                         return 'full';
6557                 }
6558         }
6559
6560         function get_extension()
6561         {
6562                 if ($this->link !== null)
6563                 {
6564                         $url = SimplePie_Misc::parse_url($this->link);
6565                         if ($url['path'] !== '')
6566                         {
6567                                 return pathinfo($url['path'], PATHINFO_EXTENSION);
6568                         }
6569                 }
6570                 return null;
6571         }
6572
6573         function get_framerate()
6574         {
6575                 if ($this->framerate !== null)
6576                 {
6577                         return $this->framerate;
6578                 }
6579                 else
6580                 {
6581                         return null;
6582                 }
6583         }
6584
6585         function get_handler()
6586         {
6587                 return $this->get_real_type(true);
6588         }
6589
6590         function get_hash($key = 0)
6591         {
6592                 $hashes = $this->get_hashes();
6593                 if (isset($hashes[$key]))
6594                 {
6595                         return $hashes[$key];
6596                 }
6597                 else
6598                 {
6599                         return null;
6600                 }
6601         }
6602
6603         function get_hashes()
6604         {
6605                 if ($this->hashes !== null)
6606                 {
6607                         return $this->hashes;
6608                 }
6609                 else
6610                 {
6611                         return null;
6612                 }
6613         }
6614
6615         function get_height()
6616         {
6617                 if ($this->height !== null)
6618                 {
6619                         return $this->height;
6620                 }
6621                 else
6622                 {
6623                         return null;
6624                 }
6625         }
6626
6627         function get_language()
6628         {
6629                 if ($this->lang !== null)
6630                 {
6631                         return $this->lang;
6632                 }
6633                 else
6634                 {
6635                         return null;
6636                 }
6637         }
6638
6639         function get_keyword($key = 0)
6640         {
6641                 $keywords = $this->get_keywords();
6642                 if (isset($keywords[$key]))
6643                 {
6644                         return $keywords[$key];
6645                 }
6646                 else
6647                 {
6648                         return null;
6649                 }
6650         }
6651
6652         function get_keywords()
6653         {
6654                 if ($this->keywords !== null)
6655                 {
6656                         return $this->keywords;
6657                 }
6658                 else
6659                 {
6660                         return null;
6661                 }
6662         }
6663
6664         function get_length()
6665         {
6666                 if ($this->length !== null)
6667                 {
6668                         return $this->length;
6669                 }
6670                 else
6671                 {
6672                         return null;
6673                 }
6674         }
6675
6676         function get_link()
6677         {
6678                 if ($this->link !== null)
6679                 {
6680                         return urldecode($this->link);
6681                 }
6682                 else
6683                 {
6684                         return null;
6685                 }
6686         }
6687
6688         function get_medium()
6689         {
6690                 if ($this->medium !== null)
6691                 {
6692                         return $this->medium;
6693                 }
6694                 else
6695                 {
6696                         return null;
6697                 }
6698         }
6699
6700         function get_player()
6701         {
6702                 if ($this->player !== null)
6703                 {
6704                         return $this->player;
6705                 }
6706                 else
6707                 {
6708                         return null;
6709                 }
6710         }
6711
6712         function get_rating($key = 0)
6713         {
6714                 $ratings = $this->get_ratings();
6715                 if (isset($ratings[$key]))
6716                 {
6717                         return $ratings[$key];
6718                 }
6719                 else
6720                 {
6721                         return null;
6722                 }
6723         }
6724
6725         function get_ratings()
6726         {
6727                 if ($this->ratings !== null)
6728                 {
6729                         return $this->ratings;
6730                 }
6731                 else
6732                 {
6733                         return null;
6734                 }
6735         }
6736
6737         function get_restriction($key = 0)
6738         {
6739                 $restrictions = $this->get_restrictions();
6740                 if (isset($restrictions[$key]))
6741                 {
6742                         return $restrictions[$key];
6743                 }
6744                 else
6745                 {
6746                         return null;
6747                 }
6748         }
6749
6750         function get_restrictions()
6751         {
6752                 if ($this->restrictions !== null)
6753                 {
6754                         return $this->restrictions;
6755                 }
6756                 else
6757                 {
6758                         return null;
6759                 }
6760         }
6761
6762         function get_sampling_rate()
6763         {
6764                 if ($this->samplingrate !== null)
6765                 {
6766                         return $this->samplingrate;
6767                 }
6768                 else
6769                 {
6770                         return null;
6771                 }
6772         }
6773
6774         function get_size()
6775         {
6776                 $length = $this->get_length();
6777                 if ($length !== null)
6778                 {
6779                         return round($length/1048576, 2);
6780                 }
6781                 else
6782                 {
6783                         return null;
6784                 }
6785         }
6786
6787         function get_thumbnail($key = 0)
6788         {
6789                 $thumbnails = $this->get_thumbnails();
6790                 if (isset($thumbnails[$key]))
6791                 {
6792                         return $thumbnails[$key];
6793                 }
6794                 else
6795                 {
6796                         return null;
6797                 }
6798         }
6799
6800         function get_thumbnails()
6801         {
6802                 if ($this->thumbnails !== null)
6803                 {
6804                         return $this->thumbnails;
6805                 }
6806                 else
6807                 {
6808                         return null;
6809                 }
6810         }
6811
6812         function get_title()
6813         {
6814                 if ($this->title !== null)
6815                 {
6816                         return $this->title;
6817                 }
6818                 else
6819                 {
6820                         return null;
6821                 }
6822         }
6823
6824         function get_type()
6825         {
6826                 if ($this->type !== null)
6827                 {
6828                         return $this->type;
6829                 }
6830                 else
6831                 {
6832                         return null;
6833                 }
6834         }
6835
6836         function get_width()
6837         {
6838                 if ($this->width !== null)
6839                 {
6840                         return $this->width;
6841                 }
6842                 else
6843                 {
6844                         return null;
6845                 }
6846         }
6847
6848         function native_embed($options='')
6849         {
6850                 return $this->embed($options, true);
6851         }
6852
6853         /**
6854          * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6855          */
6856         function embed($options = '', $native = false)
6857         {
6858                 // Set up defaults
6859                 $audio = '';
6860                 $video = '';
6861                 $alt = '';
6862                 $altclass = '';
6863                 $loop = 'false';
6864                 $width = 'auto';
6865                 $height = 'auto';
6866                 $bgcolor = '#ffffff';
6867                 $mediaplayer = '';
6868                 $widescreen = false;
6869                 $handler = $this->get_handler();
6870                 $type = $this->get_real_type();
6871
6872                 // Process options and reassign values as necessary
6873                 if (is_array($options))
6874                 {
6875                         extract($options);
6876                 }
6877                 else
6878                 {
6879                         $options = explode(',', $options);
6880                         foreach($options as $option)
6881                         {
6882                                 $opt = explode(':', $option, 2);
6883                                 if (isset($opt[0], $opt[1]))
6884                                 {
6885                                         $opt[0] = trim($opt[0]);
6886                                         $opt[1] = trim($opt[1]);
6887                                         switch ($opt[0])
6888                                         {
6889                                                 case 'audio':
6890                                                         $audio = $opt[1];
6891                                                         break;
6892
6893                                                 case 'video':
6894                                                         $video = $opt[1];
6895                                                         break;
6896
6897                                                 case 'alt':
6898                                                         $alt = $opt[1];
6899                                                         break;
6900
6901                                                 case 'altclass':
6902                                                         $altclass = $opt[1];
6903                                                         break;
6904
6905                                                 case 'loop':
6906                                                         $loop = $opt[1];
6907                                                         break;
6908
6909                                                 case 'width':
6910                                                         $width = $opt[1];
6911                                                         break;
6912
6913                                                 case 'height':
6914                                                         $height = $opt[1];
6915                                                         break;
6916
6917                                                 case 'bgcolor':
6918                                                         $bgcolor = $opt[1];
6919                                                         break;
6920
6921                                                 case 'mediaplayer':
6922                                                         $mediaplayer = $opt[1];
6923                                                         break;
6924
6925                                                 case 'widescreen':
6926                                                         $widescreen = $opt[1];
6927                                                         break;
6928                                         }
6929                                 }
6930                         }
6931                 }
6932
6933                 $mime = explode('/', $type, 2);
6934                 $mime = $mime[0];
6935
6936                 // Process values for 'auto'
6937                 if ($width == 'auto')
6938                 {
6939                         if ($mime == 'video')
6940                         {
6941                                 if ($height == 'auto')
6942                                 {
6943                                         $width = 480;
6944                                 }
6945                                 elseif ($widescreen)
6946                                 {
6947                                         $width = round((intval($height)/9)*16);
6948                                 }
6949                                 else
6950                                 {
6951                                         $width = round((intval($height)/3)*4);
6952                                 }
6953                         }
6954                         else
6955                         {
6956                                 $width = '100%';
6957                         }
6958                 }
6959
6960                 if ($height == 'auto')
6961                 {
6962                         if ($mime == 'audio')
6963                         {
6964                                 $height = 0;
6965                         }
6966                         elseif ($mime == 'video')
6967                         {
6968                                 if ($width == 'auto')
6969                                 {
6970                                         if ($widescreen)
6971                                         {
6972                                                 $height = 270;
6973                                         }
6974                                         else
6975                                         {
6976                                                 $height = 360;
6977                                         }
6978                                 }
6979                                 elseif ($widescreen)
6980                                 {
6981                                         $height = round((intval($width)/16)*9);
6982                                 }
6983                                 else
6984                                 {
6985                                         $height = round((intval($width)/4)*3);
6986                                 }
6987                         }
6988                         else
6989                         {
6990                                 $height = 376;
6991                         }
6992                 }
6993                 elseif ($mime == 'audio')
6994                 {
6995                         $height = 0;
6996                 }
6997
6998                 // Set proper placeholder value
6999                 if ($mime == 'audio')
7000                 {
7001                         $placeholder = $audio;
7002                 }
7003                 elseif ($mime == 'video')
7004                 {
7005                         $placeholder = $video;
7006                 }
7007
7008                 $embed = '';
7009
7010                 // Make sure the JS library is included
7011                 if (!$native)
7012                 {
7013                         static $javascript_outputted = null;
7014                         if (!$javascript_outputted && $this->javascript)
7015                         {
7016                                 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7017                                 $javascript_outputted = true;
7018                         }
7019                 }
7020
7021                 // Odeo Feed MP3's
7022                 if ($handler == 'odeo')
7023                 {
7024                         if ($native)
7025                         {
7026                                 $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>';
7027                         }
7028                         else
7029                         {
7030                                 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7031                         }
7032                 }
7033
7034                 // Flash
7035                 elseif ($handler == 'flash')
7036                 {
7037                         if ($native)
7038                         {
7039                                 $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>";
7040                         }
7041                         else
7042                         {
7043                                 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7044                         }
7045                 }
7046
7047                 // Flash Media Player file types.
7048                 // Preferred handler for MP3 file types.
7049                 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7050                 {
7051                         $height += 20;
7052                         if ($native)
7053                         {
7054                                 $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>";
7055                         }
7056                         else
7057                         {
7058                                 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7059                         }
7060                 }
7061
7062                 // QuickTime 7 file types.  Need to test with QuickTime 6.
7063                 // Only handle MP3's if the Flash Media Player is not present.
7064                 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7065                 {
7066                         $height += 16;
7067                         if ($native)
7068                         {
7069                                 if ($placeholder != ""){
7070                                         $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>";
7071                                 }
7072                                 else {
7073                                         $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>";
7074                                 }
7075                         }
7076                         else
7077                         {
7078                                 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7079                         }
7080                 }
7081
7082                 // Windows Media
7083                 elseif ($handler == 'wmedia')
7084                 {
7085                         $height += 45;
7086                         if ($native)
7087                         {
7088                                 $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>";
7089                         }
7090                         else
7091                         {
7092                                 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7093                         }
7094                 }
7095
7096                 // Everything else
7097                 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7098
7099                 return $embed;
7100         }
7101
7102         function get_real_type($find_handler = false)
7103         {
7104                 // If it's Odeo, let's get it out of the way.
7105                 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7106                 {
7107                         return 'odeo';
7108                 }
7109
7110                 // Mime-types by handler.
7111                 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7112                 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7113                 $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
7114                 $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
7115                 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7116
7117                 if ($this->get_type() !== null)
7118                 {
7119                         $type = strtolower($this->type);
7120                 }
7121                 else
7122                 {
7123                         $type = null;
7124                 }
7125
7126                 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7127                 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7128                 {
7129                         switch (strtolower($this->get_extension()))
7130                         {
7131                                 // Audio mime-types
7132                                 case 'aac':
7133                                 case 'adts':
7134                                         $type = 'audio/acc';
7135                                         break;
7136
7137                                 case 'aif':
7138                                 case 'aifc':
7139                                 case 'aiff':
7140                                 case 'cdda':
7141                                         $type = 'audio/aiff';
7142                                         break;
7143
7144                                 case 'bwf':
7145                                         $type = 'audio/wav';
7146                                         break;
7147
7148                                 case 'kar':
7149                                 case 'mid':
7150                                 case 'midi':
7151                                 case 'smf':
7152                                         $type = 'audio/midi';
7153                                         break;
7154
7155                                 case 'm4a':
7156                                         $type = 'audio/x-m4a';
7157                                         break;
7158
7159                                 case 'mp3':
7160                                 case 'swa':
7161                                         $type = 'audio/mp3';
7162                                         break;
7163
7164                                 case 'wav':
7165                                         $type = 'audio/wav';
7166                                         break;
7167
7168                                 case 'wax':
7169                                         $type = 'audio/x-ms-wax';
7170                                         break;
7171
7172                                 case 'wma':
7173                                         $type = 'audio/x-ms-wma';
7174                                         break;
7175
7176                                 // Video mime-types
7177                                 case '3gp':
7178                                 case '3gpp':
7179                                         $type = 'video/3gpp';
7180                                         break;
7181
7182                                 case '3g2':
7183                                 case '3gp2':
7184                                         $type = 'video/3gpp2';
7185                                         break;
7186
7187                                 case 'asf':
7188                                         $type = 'video/x-ms-asf';
7189                                         break;
7190
7191                                 case 'flv':
7192                                         $type = 'video/x-flv';
7193                                         break;
7194
7195                                 case 'm1a':
7196                                 case 'm1s':
7197                                 case 'm1v':
7198                                 case 'm15':
7199                                 case 'm75':
7200                                 case 'mp2':
7201                                 case 'mpa':
7202                                 case 'mpeg':
7203                                 case 'mpg':
7204                                 case 'mpm':
7205                                 case 'mpv':
7206                                         $type = 'video/mpeg';
7207                                         break;
7208
7209                                 case 'm4v':
7210                                         $type = 'video/x-m4v';
7211                                         break;
7212
7213                                 case 'mov':
7214                                 case 'qt':
7215                                         $type = 'video/quicktime';
7216                                         break;
7217
7218                                 case 'mp4':
7219                                 case 'mpg4':
7220                                         $type = 'video/mp4';
7221                                         break;
7222
7223                                 case 'sdv':
7224                                         $type = 'video/sd-video';
7225                                         break;
7226
7227                                 case 'wm':
7228                                         $type = 'video/x-ms-wm';
7229                                         break;
7230
7231                                 case 'wmv':
7232                                         $type = 'video/x-ms-wmv';
7233                                         break;
7234
7235                                 case 'wvx':
7236                                         $type = 'video/x-ms-wvx';
7237                                         break;
7238
7239                                 // Flash mime-types
7240                                 case 'spl':
7241                                         $type = 'application/futuresplash';
7242                                         break;
7243
7244                                 case 'swf':
7245                                         $type = 'application/x-shockwave-flash';
7246                                         break;
7247                         }
7248                 }
7249
7250                 if ($find_handler)
7251                 {
7252                         if (in_array($type, $types_flash))
7253                         {
7254                                 return 'flash';
7255                         }
7256                         elseif (in_array($type, $types_fmedia))
7257                         {
7258                                 return 'fmedia';
7259                         }
7260                         elseif (in_array($type, $types_quicktime))
7261                         {
7262                                 return 'quicktime';
7263                         }
7264                         elseif (in_array($type, $types_wmedia))
7265                         {
7266                                 return 'wmedia';
7267                         }
7268                         elseif (in_array($type, $types_mp3))
7269                         {
7270                                 return 'mp3';
7271                         }
7272                         else
7273                         {
7274                                 return null;
7275                         }
7276                 }
7277                 else
7278                 {
7279                         return $type;
7280                 }
7281         }
7282 }
7283
7284 class SimplePie_Caption
7285 {
7286         var $type;
7287         var $lang;
7288         var $startTime;
7289         var $endTime;
7290         var $text;
7291
7292         // Constructor, used to input the data
7293         function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7294         {
7295                 $this->type = $type;
7296                 $this->lang = $lang;
7297                 $this->startTime = $startTime;
7298                 $this->endTime = $endTime;
7299                 $this->text = $text;
7300         }
7301
7302         function __toString()
7303         {
7304                 // There is no $this->data here
7305                 return md5(serialize($this));
7306         }
7307
7308         function get_endtime()
7309         {
7310                 if ($this->endTime !== null)
7311                 {
7312                         return $this->endTime;
7313                 }
7314                 else
7315                 {
7316                         return null;
7317                 }
7318         }
7319
7320         function get_language()
7321         {
7322                 if ($this->lang !== null)
7323                 {
7324                         return $this->lang;
7325                 }
7326                 else
7327                 {
7328                         return null;
7329                 }
7330         }
7331
7332         function get_starttime()
7333         {
7334                 if ($this->startTime !== null)
7335                 {
7336                         return $this->startTime;
7337                 }
7338                 else
7339                 {
7340                         return null;
7341                 }
7342         }
7343
7344         function get_text()
7345         {
7346                 if ($this->text !== null)
7347                 {
7348                         return $this->text;
7349                 }
7350                 else
7351                 {
7352                         return null;
7353                 }
7354         }
7355
7356         function get_type()
7357         {
7358                 if ($this->type !== null)
7359                 {
7360                         return $this->type;
7361                 }
7362                 else
7363                 {
7364                         return null;
7365                 }
7366         }
7367 }
7368
7369 class SimplePie_Credit
7370 {
7371         var $role;
7372         var $scheme;
7373         var $name;
7374
7375         // Constructor, used to input the data
7376         function SimplePie_Credit($role = null, $scheme = null, $name = null)
7377         {
7378                 $this->role = $role;
7379                 $this->scheme = $scheme;
7380                 $this->name = $name;
7381         }
7382
7383         function __toString()
7384         {
7385                 // There is no $this->data here
7386                 return md5(serialize($this));
7387         }
7388
7389         function get_role()
7390         {
7391                 if ($this->role !== null)
7392                 {
7393                         return $this->role;
7394                 }
7395                 else
7396                 {
7397                         return null;
7398                 }
7399         }
7400
7401         function get_scheme()
7402         {
7403                 if ($this->scheme !== null)
7404                 {
7405                         return $this->scheme;
7406                 }
7407                 else
7408                 {
7409                         return null;
7410                 }
7411         }
7412
7413         function get_name()
7414         {
7415                 if ($this->name !== null)
7416                 {
7417                         return $this->name;
7418                 }
7419                 else
7420                 {
7421                         return null;
7422                 }
7423         }
7424 }
7425
7426 class SimplePie_Copyright
7427 {
7428         var $url;
7429         var $label;
7430
7431         // Constructor, used to input the data
7432         function SimplePie_Copyright($url = null, $label = null)
7433         {
7434                 $this->url = $url;
7435                 $this->label = $label;
7436         }
7437
7438         function __toString()
7439         {
7440                 // There is no $this->data here
7441                 return md5(serialize($this));
7442         }
7443
7444         function get_url()
7445         {
7446                 if ($this->url !== null)
7447                 {
7448                         return $this->url;
7449                 }
7450                 else
7451                 {
7452                         return null;
7453                 }
7454         }
7455
7456         function get_attribution()
7457         {
7458                 if ($this->label !== null)
7459                 {
7460                         return $this->label;
7461                 }
7462                 else
7463                 {
7464                         return null;
7465                 }
7466         }
7467 }
7468
7469 class SimplePie_Rating
7470 {
7471         var $scheme;
7472         var $value;
7473
7474         // Constructor, used to input the data
7475         function SimplePie_Rating($scheme = null, $value = null)
7476         {
7477                 $this->scheme = $scheme;
7478                 $this->value = $value;
7479         }
7480
7481         function __toString()
7482         {
7483                 // There is no $this->data here
7484                 return md5(serialize($this));
7485         }
7486
7487         function get_scheme()
7488         {
7489                 if ($this->scheme !== null)
7490                 {
7491                         return $this->scheme;
7492                 }
7493                 else
7494                 {
7495                         return null;
7496                 }
7497         }
7498
7499         function get_value()
7500         {
7501                 if ($this->value !== null)
7502                 {
7503                         return $this->value;
7504                 }
7505                 else
7506                 {
7507                         return null;
7508                 }
7509         }
7510 }
7511
7512 class SimplePie_Restriction
7513 {
7514         var $relationship;
7515         var $type;
7516         var $value;
7517
7518         // Constructor, used to input the data
7519         function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7520         {
7521                 $this->relationship = $relationship;
7522                 $this->type = $type;
7523                 $this->value = $value;
7524         }
7525
7526         function __toString()
7527         {
7528                 // There is no $this->data here
7529                 return md5(serialize($this));
7530         }
7531
7532         function get_relationship()
7533         {
7534                 if ($this->relationship !== null)
7535                 {
7536                         return $this->relationship;
7537                 }
7538                 else
7539                 {
7540                         return null;
7541                 }
7542         }
7543
7544         function get_type()
7545         {
7546                 if ($this->type !== null)
7547                 {
7548                         return $this->type;
7549                 }
7550                 else
7551                 {
7552                         return null;
7553                 }
7554         }
7555
7556         function get_value()
7557         {
7558                 if ($this->value !== null)
7559                 {
7560                         return $this->value;
7561                 }
7562                 else
7563                 {
7564                         return null;
7565                 }
7566         }
7567 }
7568
7569 /**
7570  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7571  */
7572 class SimplePie_File
7573 {
7574         var $url;
7575         var $useragent;
7576         var $success = true;
7577         var $headers = array();
7578         var $body;
7579         var $status_code;
7580         var $redirects = 0;
7581         var $error;
7582         var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7583
7584         function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7585         {
7586                 if (class_exists('idna_convert'))
7587                 {
7588                         $idn =& new idna_convert;
7589                         $parsed = SimplePie_Misc::parse_url($url);
7590                         $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7591                 }
7592                 $this->url = $url;
7593                 $this->useragent = $useragent;
7594                 if (preg_match('/^http(s)?:\/\//i', $url))
7595                 {
7596                         if ($useragent === null)
7597                         {
7598                                 $useragent = ini_get('user_agent');
7599                                 $this->useragent = $useragent;
7600                         }
7601                         if (!is_array($headers))
7602                         {
7603                                 $headers = array();
7604                         }
7605                         if (!$force_fsockopen && function_exists('curl_exec'))
7606                         {
7607                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7608                                 $fp = curl_init();
7609                                 $headers2 = array();
7610                                 foreach ($headers as $key => $value)
7611                                 {
7612                                         $headers2[] = "$key: $value";
7613                                 }
7614                                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7615                                 {
7616                                         curl_setopt($fp, CURLOPT_ENCODING, '');
7617                                 }
7618                                 curl_setopt($fp, CURLOPT_URL, $url);
7619                                 curl_setopt($fp, CURLOPT_HEADER, 1);
7620                                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7621                                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7622                                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7623                                 curl_setopt($fp, CURLOPT_REFERER, $url);
7624                                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7625                                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7626                                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7627                                 {
7628                                         curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7629                                         curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7630                                 }
7631
7632                                 $this->headers = curl_exec($fp);
7633                                 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7634                                 {
7635                                         curl_setopt($fp, CURLOPT_ENCODING, 'none');
7636                                         $this->headers = curl_exec($fp);
7637                                 }
7638                                 if (curl_errno($fp))
7639                                 {
7640                                         $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7641                                         $this->success = false;
7642                                 }
7643                                 else
7644                                 {
7645                                         $info = curl_getinfo($fp);
7646                                         curl_close($fp);
7647                                         $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7648                                         $this->headers = array_pop($this->headers);
7649                                         $parser =& new SimplePie_HTTP_Parser($this->headers);
7650                                         if ($parser->parse())
7651                                         {
7652                                                 $this->headers = $parser->headers;
7653                                                 $this->body = $parser->body;
7654                                                 $this->status_code = $parser->status_code;
7655                                                 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)
7656                                                 {
7657                                                         $this->redirects++;
7658                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7659                                                         return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7660                                                 }
7661                                         }
7662                                 }
7663                         }
7664                         else
7665                         {
7666                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7667                                 $url_parts = parse_url($url);
7668                                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7669                                 {
7670                                         $url_parts['host'] = "ssl://$url_parts[host]";
7671                                         $url_parts['port'] = 443;
7672                                 }
7673                                 if (!isset($url_parts['port']))
7674                                 {
7675                                         $url_parts['port'] = 80;
7676                                 }
7677                                 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7678                                 if (!$fp)
7679                                 {
7680                                         $this->error = 'fsockopen error: ' . $errstr;
7681                                         $this->success = false;
7682                                 }
7683                                 else
7684                                 {
7685                                         stream_set_timeout($fp, $timeout);
7686                                         if (isset($url_parts['path']))
7687                                         {
7688                                                 if (isset($url_parts['query']))
7689                                                 {
7690                                                         $get = "$url_parts[path]?$url_parts[query]";
7691                                                 }
7692                                                 else
7693                                                 {
7694                                                         $get = $url_parts['path'];
7695                                                 }
7696                                         }
7697                                         else
7698                                         {
7699                                                 $get = '/';
7700                                         }
7701                                         $out = "GET $get HTTP/1.0\r\n";
7702                                         $out .= "Host: $url_parts[host]\r\n";
7703                                         $out .= "User-Agent: $useragent\r\n";
7704                                         if (extension_loaded('zlib'))
7705                                         {
7706                                                 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7707                                         }
7708
7709                                         if (isset($url_parts['user']) && isset($url_parts['pass']))
7710                                         {
7711                                                 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7712                                         }
7713                                         foreach ($headers as $key => $value)
7714                                         {
7715                                                 $out .= "$key: $value\r\n";
7716                                         }
7717                                         $out .= "Connection: Close\r\n\r\n";
7718                                         fwrite($fp, $out);
7719
7720                                         $info = stream_get_meta_data($fp);
7721
7722                                         $this->headers = '';
7723                                         while (!$info['eof'] && !$info['timed_out'])
7724                                         {
7725                                                 $this->headers .= fread($fp, 1160);
7726                                                 $info = stream_get_meta_data($fp);
7727                                         }
7728                                         if (!$info['timed_out'])
7729                                         {
7730                                                 $parser =& new SimplePie_HTTP_Parser($this->headers);
7731                                                 if ($parser->parse())
7732                                                 {
7733                                                         $this->headers = $parser->headers;
7734                                                         $this->body = $parser->body;
7735                                                         $this->status_code = $parser->status_code;
7736                                                         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)
7737                                                         {
7738                                                                 $this->redirects++;
7739                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7740                                                                 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7741                                                         }
7742                                                         if (isset($this->headers['content-encoding']))
7743                                                         {
7744                                                                 // Hey, we act dumb elsewhere, so let's do that here too
7745                                                                 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7746                                                                 {
7747                                                                         case 'gzip':
7748                                                                         case 'x-gzip':
7749                                                                                 $decoder = new SimplePie_gzdecode($this->body);
7750                                                                                 if (!$decoder->parse())
7751                                                                                 {
7752                                                                                         $this->error = 'Unable to decode HTTP "gzip" stream';
7753                                                                                         $this->success = false;
7754                                                                                 }
7755                                                                                 else
7756                                                                                 {
7757                                                                                         $this->body = $decoder->data;
7758                                                                                 }
7759                                                                                 break;
7760
7761                                                                         case 'deflate':
7762                                                                                 if (($body = gzuncompress($this->body)) === false)
7763                                                                                 {
7764                                                                                         if (($body = gzinflate($this->body)) === false)
7765                                                                                         {
7766                                                                                                 $this->error = 'Unable to decode HTTP "deflate" stream';
7767                                                                                                 $this->success = false;
7768                                                                                         }
7769                                                                                 }
7770                                                                                 $this->body = $body;
7771                                                                                 break;
7772
7773                                                                         default:
7774                                                                                 $this->error = 'Unknown content coding';
7775                                                                                 $this->success = false;
7776                                                                 }
7777                                                         }
7778                                                 }
7779                                         }
7780                                         else
7781                                         {
7782                                                 $this->error = 'fsocket timed out';
7783                                                 $this->success = false;
7784                                         }
7785                                         fclose($fp);
7786                                 }
7787                         }
7788                 }
7789                 else
7790                 {
7791                         $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7792                         if (!$this->body = file_get_contents($url))
7793                         {
7794                                 $this->error = 'file_get_contents could not read the file';
7795                                 $this->success = false;
7796                         }
7797                 }
7798         }
7799 }
7800
7801 /**
7802  * HTTP Response Parser
7803  *
7804  * @package SimplePie
7805  */
7806 class SimplePie_HTTP_Parser
7807 {
7808         /**
7809          * HTTP Version
7810          *
7811          * @access public
7812          * @var float
7813          */
7814         var $http_version = 0.0;
7815
7816         /**
7817          * Status code
7818          *
7819          * @access public
7820          * @var int
7821          */
7822         var $status_code = 0;
7823
7824         /**
7825          * Reason phrase
7826          *
7827          * @access public
7828          * @var string
7829          */
7830         var $reason = '';
7831
7832         /**
7833          * Key/value pairs of the headers
7834          *
7835          * @access public
7836          * @var array
7837          */
7838         var $headers = array();
7839
7840         /**
7841          * Body of the response
7842          *
7843          * @access public
7844          * @var string
7845          */
7846         var $body = '';
7847
7848         /**
7849          * Current state of the state machine
7850          *
7851          * @access private
7852          * @var string
7853          */
7854         var $state = 'http_version';
7855
7856         /**
7857          * Input data
7858          *
7859          * @access private
7860          * @var string
7861          */
7862         var $data = '';
7863
7864         /**
7865          * Input data length (to avoid calling strlen() everytime this is needed)
7866          *
7867          * @access private
7868          * @var int
7869          */
7870         var $data_length = 0;
7871
7872         /**
7873          * Current position of the pointer
7874          *
7875          * @var int
7876          * @access private
7877          */
7878         var $position = 0;
7879
7880         /**
7881          * Name of the hedaer currently being parsed
7882          *
7883          * @access private
7884          * @var string
7885          */
7886         var $name = '';
7887
7888         /**
7889          * Value of the hedaer currently being parsed
7890          *
7891          * @access private
7892          * @var string
7893          */
7894         var $value = '';
7895
7896         /**
7897          * Create an instance of the class with the input data
7898          *
7899          * @access public
7900          * @param string $data Input data
7901          */
7902         function SimplePie_HTTP_Parser($data)
7903         {
7904                 $this->data = $data;
7905                 $this->data_length = strlen($this->data);
7906         }
7907
7908         /**
7909          * Parse the input data
7910          *
7911          * @access public
7912          * @return bool true on success, false on failure
7913          */
7914         function parse()
7915         {
7916                 while ($this->state && $this->state !== 'emit' && $this->has_data())
7917                 {
7918                         $state = $this->state;
7919                         $this->$state();
7920                 }
7921                 $this->data = '';
7922                 if ($this->state === 'emit' || $this->state === 'body')
7923                 {
7924                         return true;
7925                 }
7926                 else
7927                 {
7928                         $this->http_version = '';
7929                         $this->status_code = '';
7930                         $this->reason = '';
7931                         $this->headers = array();
7932                         $this->body = '';
7933                         return false;
7934                 }
7935         }
7936
7937         /**
7938          * Check whether there is data beyond the pointer
7939          *
7940          * @access private
7941          * @return bool true if there is further data, false if not
7942          */
7943         function has_data()
7944         {
7945                 return (bool) ($this->position < $this->data_length);
7946         }
7947
7948         /**
7949          * See if the next character is LWS
7950          *
7951          * @access private
7952          * @return bool true if the next character is LWS, false if not
7953          */
7954         function is_linear_whitespace()
7955         {
7956                 return (bool) ($this->data[$this->position] === "\x09"
7957                         || $this->data[$this->position] === "\x20"
7958                         || ($this->data[$this->position] === "\x0A"
7959                                 && isset($this->data[$this->position + 1])
7960                                 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7961         }
7962
7963         /**
7964          * Parse the HTTP version
7965          *
7966          * @access private
7967          */
7968         function http_version()
7969         {
7970                 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7971                 {
7972                         $len = strspn($this->data, '0123456789.', 5);
7973                         $this->http_version = substr($this->data, 5, $len);
7974                         $this->position += 5 + $len;
7975                         if (substr_count($this->http_version, '.') <= 1)
7976                         {
7977                                 $this->http_version = (float) $this->http_version;
7978                                 $this->position += strspn($this->data, "\x09\x20", $this->position);
7979                                 $this->state = 'status';
7980                         }
7981                         else
7982                         {
7983                                 $this->state = false;
7984                         }
7985                 }
7986                 else
7987                 {
7988                         $this->state = false;
7989                 }
7990         }
7991
7992         /**
7993          * Parse the status code
7994          *
7995          * @access private
7996          */
7997         function status()
7998         {
7999                 if ($len = strspn($this->data, '0123456789', $this->position))
8000                 {
8001                         $this->status_code = (int) substr($this->data, $this->position, $len);
8002                         $this->position += $len;
8003                         $this->state = 'reason';
8004                 }
8005                 else
8006                 {
8007                         $this->state = false;
8008                 }
8009         }
8010
8011         /**
8012          * Parse the reason phrase
8013          *
8014          * @access private
8015          */
8016         function reason()
8017         {
8018                 $len = strcspn($this->data, "\x0A", $this->position);
8019                 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8020                 $this->position += $len + 1;
8021                 $this->state = 'new_line';
8022         }
8023
8024         /**
8025          * Deal with a new line, shifting data around as needed
8026          *
8027          * @access private
8028          */
8029         function new_line()
8030         {
8031                 $this->value = trim($this->value, "\x0D\x20");
8032                 if ($this->name !== '' && $this->value !== '')
8033                 {
8034                         $this->name = strtolower($this->name);
8035                         if (isset($this->headers[$this->name]))
8036                         {
8037                                 $this->headers[$this->name] .= ', ' . $this->value;
8038                         }
8039                         else
8040                         {
8041                                 $this->headers[$this->name] = $this->value;
8042                         }
8043                 }
8044                 $this->name = '';
8045                 $this->value = '';
8046                 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8047                 {
8048                         $this->position += 2;
8049                         $this->state = 'body';
8050                 }
8051                 elseif ($this->data[$this->position] === "\x0A")
8052                 {
8053                         $this->position++;
8054                         $this->state = 'body';
8055                 }
8056                 else
8057                 {
8058                         $this->state = 'name';
8059                 }
8060         }
8061
8062         /**
8063          * Parse a header name
8064          *
8065          * @access private
8066          */
8067         function name()
8068         {
8069                 $len = strcspn($this->data, "\x0A:", $this->position);
8070                 if (isset($this->data[$this->position + $len]))
8071                 {
8072                         if ($this->data[$this->position + $len] === "\x0A")
8073                         {
8074                                 $this->position += $len;
8075                                 $this->state = 'new_line';
8076                         }
8077                         else
8078                         {
8079                                 $this->name = substr($this->data, $this->position, $len);
8080                                 $this->position += $len + 1;
8081                                 $this->state = 'value';
8082                         }
8083                 }
8084                 else
8085                 {
8086                         $this->state = false;
8087                 }
8088         }
8089
8090         /**
8091          * Parse LWS, replacing consecutive LWS characters with a single space
8092          *
8093          * @access private
8094          */
8095         function linear_whitespace()
8096         {
8097                 do
8098                 {
8099                         if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8100                         {
8101                                 $this->position += 2;
8102                         }
8103                         elseif ($this->data[$this->position] === "\x0A")
8104                         {
8105                                 $this->position++;
8106                         }
8107                         $this->position += strspn($this->data, "\x09\x20", $this->position);
8108                 } while ($this->has_data() && $this->is_linear_whitespace());
8109                 $this->value .= "\x20";
8110         }
8111
8112         /**
8113          * See what state to move to while within non-quoted header values
8114          *
8115          * @access private
8116          */
8117         function value()
8118         {
8119                 if ($this->is_linear_whitespace())
8120                 {
8121                         $this->linear_whitespace();
8122                 }
8123                 else
8124                 {
8125                         switch ($this->data[$this->position])
8126                         {
8127                                 case '"':
8128                                         $this->position++;
8129                                         $this->state = 'quote';
8130                                         break;
8131
8132                                 case "\x0A":
8133                                         $this->position++;
8134                                         $this->state = 'new_line';
8135                                         break;
8136
8137                                 default:
8138                                         $this->state = 'value_char';
8139                                         break;
8140                         }
8141                 }
8142         }
8143
8144         /**
8145          * Parse a header value while outside quotes
8146          *
8147          * @access private
8148          */
8149         function value_char()
8150         {
8151                 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8152                 $this->value .= substr($this->data, $this->position, $len);
8153                 $this->position += $len;
8154                 $this->state = 'value';
8155         }
8156
8157         /**
8158          * See what state to move to while within quoted header values
8159          *
8160          * @access private
8161          */
8162         function quote()
8163         {
8164                 if ($this->is_linear_whitespace())
8165                 {
8166                         $this->linear_whitespace();
8167                 }
8168                 else
8169                 {
8170                         switch ($this->data[$this->position])
8171                         {
8172                                 case '"':
8173                                         $this->position++;
8174                                         $this->state = 'value';
8175                                         break;
8176
8177                                 case "\x0A":
8178                                         $this->position++;
8179                                         $this->state = 'new_line';
8180                                         break;
8181
8182                                 case '\\':
8183                                         $this->position++;
8184                                         $this->state = 'quote_escaped';
8185                                         break;
8186
8187                                 default:
8188                                         $this->state = 'quote_char';
8189                                         break;
8190                         }
8191                 }
8192         }
8193
8194         /**
8195          * Parse a header value while within quotes
8196          *
8197          * @access private
8198          */
8199         function quote_char()
8200         {
8201                 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8202                 $this->value .= substr($this->data, $this->position, $len);
8203                 $this->position += $len;
8204                 $this->state = 'value';
8205         }
8206
8207         /**
8208          * Parse an escaped character within quotes
8209          *
8210          * @access private
8211          */
8212         function quote_escaped()
8213         {
8214                 $this->value .= $this->data[$this->position];
8215                 $this->position++;
8216                 $this->state = 'quote';
8217         }
8218
8219         /**
8220          * Parse the body
8221          *
8222          * @access private
8223          */
8224         function body()
8225         {
8226                 $this->body = substr($this->data, $this->position);
8227                 $this->state = 'emit';
8228         }
8229 }
8230
8231 /**
8232  * gzdecode
8233  *
8234  * @package SimplePie
8235  */
8236 class SimplePie_gzdecode
8237 {
8238         /**
8239          * Compressed data
8240          *
8241          * @access private
8242          * @see gzdecode::$data
8243          */
8244         var $compressed_data;
8245
8246         /**
8247          * Size of compressed data
8248          *
8249          * @access private
8250          */
8251         var $compressed_size;
8252
8253         /**
8254          * Minimum size of a valid gzip string
8255          *
8256          * @access private
8257          */
8258         var $min_compressed_size = 18;
8259
8260         /**
8261          * Current position of pointer
8262          *
8263          * @access private
8264          */
8265         var $position = 0;
8266
8267         /**
8268          * Flags (FLG)
8269          *
8270          * @access private
8271          */
8272         var $flags;
8273
8274         /**
8275          * Uncompressed data
8276          *
8277          * @access public
8278          * @see gzdecode::$compressed_data
8279          */
8280         var $data;
8281
8282         /**
8283          * Modified time
8284          *
8285          * @access public
8286          */
8287         var $MTIME;
8288
8289         /**
8290          * Extra Flags
8291          *
8292          * @access public
8293          */
8294         var $XFL;
8295
8296         /**
8297          * Operating System
8298          *
8299          * @access public
8300          */
8301         var $OS;
8302
8303         /**
8304          * Subfield ID 1
8305          *
8306          * @access public
8307          * @see gzdecode::$extra_field
8308          * @see gzdecode::$SI2
8309          */
8310         var $SI1;
8311
8312         /**
8313          * Subfield ID 2
8314          *
8315          * @access public
8316          * @see gzdecode::$extra_field
8317          * @see gzdecode::$SI1
8318          */
8319         var $SI2;
8320
8321         /**
8322          * Extra field content
8323          *
8324          * @access public
8325          * @see gzdecode::$SI1
8326          * @see gzdecode::$SI2
8327          */
8328         var $extra_field;
8329
8330         /**
8331          * Original filename
8332          *
8333          * @access public
8334          */
8335         var $filename;
8336
8337         /**
8338          * Human readable comment
8339          *
8340          * @access public
8341          */
8342         var $comment;
8343
8344         /**
8345          * Don't allow anything to be set
8346          *
8347          * @access public
8348          */
8349         function __set($name, $value)
8350         {
8351                 trigger_error("Cannot write property $name", E_USER_ERROR);
8352         }
8353
8354         /**
8355          * Set the compressed string and related properties
8356          *
8357          * @access public
8358          */
8359         function SimplePie_gzdecode($data)
8360         {
8361                 $this->compressed_data = $data;
8362                 $this->compressed_size = strlen($data);
8363         }
8364
8365         /**
8366          * Decode the GZIP stream
8367          *
8368          * @access public
8369          */
8370         function parse()
8371         {
8372                 if ($this->compressed_size >= $this->min_compressed_size)
8373                 {
8374                         // Check ID1, ID2, and CM
8375                         if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8376                         {
8377                                 return false;
8378                         }
8379
8380                         // Get the FLG (FLaGs)
8381                         $this->flags = ord($this->compressed_data[3]);
8382
8383                         // FLG bits above (1 << 4) are reserved
8384                         if ($this->flags > 0x1F)
8385                         {
8386                                 return false;
8387                         }
8388
8389                         // Advance the pointer after the above
8390                         $this->position += 4;
8391
8392                         // MTIME
8393                         $mtime = substr($this->compressed_data, $this->position, 4);
8394                         // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8395                         if (current(unpack('S', "\x00\x01")) === 1)
8396                         {
8397                                 $mtime = strrev($mtime);
8398                         }
8399                         $this->MTIME = current(unpack('l', $mtime));
8400                         $this->position += 4;
8401
8402                         // Get the XFL (eXtra FLags)
8403                         $this->XFL = ord($this->compressed_data[$this->position++]);
8404
8405                         // Get the OS (Operating System)
8406                         $this->OS = ord($this->compressed_data[$this->position++]);
8407
8408                         // Parse the FEXTRA
8409                         if ($this->flags & 4)
8410                         {
8411                                 // Read subfield IDs
8412                                 $this->SI1 = $this->compressed_data[$this->position++];
8413                                 $this->SI2 = $this->compressed_data[$this->position++];
8414
8415                                 // SI2 set to zero is reserved for future use
8416                                 if ($this->SI2 === "\x00")
8417                                 {
8418                                         return false;
8419                                 }
8420
8421                                 // Get the length of the extra field
8422                                 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8423                                 $position += 2;
8424
8425                                 // Check the length of the string is still valid
8426                                 $this->min_compressed_size += $len + 4;
8427                                 if ($this->compressed_size >= $this->min_compressed_size)
8428                                 {
8429                                         // Set the extra field to the given data
8430                                         $this->extra_field = substr($this->compressed_data, $this->position, $len);
8431                                         $this->position += $len;
8432                                 }
8433                                 else
8434                                 {
8435                                         return false;
8436                                 }
8437                         }
8438
8439                         // Parse the FNAME
8440                         if ($this->flags & 8)
8441                         {
8442                                 // Get the length of the filename
8443                                 $len = strspn($this->compressed_data, "\x00", $this->position);
8444
8445                                 // Check the length of the string is still valid
8446                                 $this->min_compressed_size += $len + 1;
8447                                 if ($this->compressed_size >= $this->min_compressed_size)
8448                                 {
8449                                         // Set the original filename to the given string
8450                                         $this->filename = substr($this->compressed_data, $this->position, $len);
8451                                         $this->position += $len + 1;
8452                                 }
8453                                 else
8454                                 {
8455                                         return false;
8456                                 }
8457                         }
8458
8459                         // Parse the FCOMMENT
8460                         if ($this->flags & 16)
8461                         {
8462                                 // Get the length of the comment
8463                                 $len = strspn($this->compressed_data, "\x00", $this->position);
8464
8465                                 // Check the length of the string is still valid
8466                                 $this->min_compressed_size += $len + 1;
8467                                 if ($this->compressed_size >= $this->min_compressed_size)
8468                                 {
8469                                         // Set the original comment to the given string
8470                                         $this->comment = substr($this->compressed_data, $this->position, $len);
8471                                         $this->position += $len + 1;
8472                                 }
8473                                 else
8474                                 {
8475                                         return false;
8476                                 }
8477                         }
8478
8479                         // Parse the FHCRC
8480                         if ($this->flags & 2)
8481                         {
8482                                 // Check the length of the string is still valid
8483                                 $this->min_compressed_size += $len + 2;
8484                                 if ($this->compressed_size >= $this->min_compressed_size)
8485                                 {
8486                                         // Read the CRC
8487                                         $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8488
8489                                         // Check the CRC matches
8490                                         if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8491                                         {
8492                                                 $this->position += 2;
8493                                         }
8494                                         else
8495                                         {
8496                                                 return false;
8497                                         }
8498                                 }
8499                                 else
8500                                 {
8501                                         return false;
8502                                 }
8503                         }
8504
8505                         // Decompress the actual data
8506                         if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8507                         {
8508                                 return false;
8509                         }
8510                         else
8511                         {
8512                                 $this->position = $this->compressed_size - 8;
8513                         }
8514
8515                         // Check CRC of data
8516                         $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8517                         $this->position += 4;
8518                         /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8519                         {
8520                                 return false;
8521                         }*/
8522
8523                         // Check ISIZE of data
8524                         $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8525                         $this->position += 4;
8526                         if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8527                         {
8528                                 return false;
8529                         }
8530
8531                         // Wow, against all odds, we've actually got a valid gzip string
8532                         return true;
8533                 }
8534                 else
8535                 {
8536                         return false;
8537                 }
8538         }
8539 }
8540
8541 class SimplePie_Cache
8542 {
8543         /**
8544          * Don't call the constructor. Please.
8545          *
8546          * @access private
8547          */
8548         function SimplePie_Cache()
8549         {
8550                 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8551         }
8552
8553         /**
8554          * Create a new SimplePie_Cache object
8555          *
8556          * @static
8557          * @access public
8558          */
8559         function create($location, $filename, $extension)
8560         {
8561                 return new SimplePie_Cache_File($location, $filename, $extension);
8562         }
8563 }
8564
8565 class SimplePie_Cache_File
8566 {
8567         var $location;
8568         var $filename;
8569         var $extension;
8570         var $name;
8571
8572         function SimplePie_Cache_File($location, $filename, $extension)
8573         {
8574                 $this->location = $location;
8575                 $this->filename = rawurlencode($filename);
8576                 $this->extension = rawurlencode($extension);
8577                 $this->name = "$location/$this->filename.$this->extension";
8578         }
8579
8580         function save($data)
8581         {
8582                 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8583                 {
8584                         if (is_a($data, 'SimplePie'))
8585                         {
8586                                 $data = $data->data;
8587                         }
8588
8589                         $data = serialize($data);
8590
8591                         if (function_exists('file_put_contents'))
8592                         {
8593                                 return (bool) file_put_contents($this->name, $data);
8594                         }
8595                         else
8596                         {
8597                                 $fp = fopen($this->name, 'wb');
8598                                 if ($fp)
8599                                 {
8600                                         fwrite($fp, $data);
8601                                         fclose($fp);
8602                                         return true;
8603                                 }
8604                         }
8605                 }
8606                 return false;
8607         }
8608
8609         function load()
8610         {
8611                 if (file_exists($this->name) && is_readable($this->name))
8612                 {
8613                         return unserialize(file_get_contents($this->name));
8614                 }
8615                 return false;
8616         }
8617
8618         function mtime()
8619         {
8620                 if (file_exists($this->name))
8621                 {
8622                         return filemtime($this->name);
8623                 }
8624                 return false;
8625         }
8626
8627         function touch()
8628         {
8629                 if (file_exists($this->name))
8630                 {
8631                         return touch($this->name);
8632                 }
8633                 return false;
8634         }
8635
8636         function unlink()
8637         {
8638                 if (file_exists($this->name))
8639                 {
8640                         return unlink($this->name);
8641                 }
8642                 return false;
8643         }
8644 }
8645
8646 class SimplePie_Misc
8647 {
8648         function time_hms($seconds)
8649         {
8650                 $time = '';
8651
8652                 $hours = floor($seconds / 3600);
8653                 $remainder = $seconds % 3600;
8654                 if ($hours > 0)
8655                 {
8656                         $time .= $hours.':';
8657                 }
8658
8659                 $minutes = floor($remainder / 60);
8660                 $seconds = $remainder % 60;
8661                 if ($minutes < 10 && $hours > 0)
8662                 {
8663                         $minutes = '0' . $minutes;
8664                 }
8665                 if ($seconds < 10)
8666                 {
8667                         $seconds = '0' . $seconds;
8668                 }
8669
8670                 $time .= $minutes.':';
8671                 $time .= $seconds;
8672
8673                 return $time;
8674         }
8675
8676         function absolutize_url($relative, $base)
8677         {
8678                 if ($relative !== '')
8679                 {
8680                         $relative = SimplePie_Misc::parse_url($relative);
8681                         if ($relative['scheme'] !== '')
8682                         {
8683                                 $target = $relative;
8684                         }
8685                         elseif ($base !== '')
8686                         {
8687                                 $base = SimplePie_Misc::parse_url($base);
8688                                 $target = SimplePie_Misc::parse_url('');
8689                                 if ($relative['authority'] !== '')
8690                                 {
8691                                         $target = $relative;
8692                                         $target['scheme'] = $base['scheme'];
8693                                 }
8694                                 else
8695                                 {
8696                                         $target['scheme'] = $base['scheme'];
8697                                         $target['authority'] = $base['authority'];
8698                                         if ($relative['path'] !== '')
8699                                         {
8700                                                 if (strpos($relative['path'], '/') === 0)
8701                                                 {
8702                                                         $target['path'] = $relative['path'];
8703                                                 }
8704                                                 elseif ($base['authority'] !== '' && $base['path'] === '')
8705                                                 {
8706                                                         $target['path'] = '/' . $relative['path'];
8707                                                 }
8708                                                 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8709                                                 {
8710                                                         $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8711                                                 }
8712                                                 else
8713                                                 {
8714                                                         $target['path'] = $relative['path'];
8715                                                 }
8716                                                 $target['query'] = $relative['query'];
8717                                         }
8718                                         else
8719                                         {
8720                                                 $target['path'] = $base['path'];
8721                                                 if ($relative['query'] !== '')
8722                                                 {
8723                                                         $target['query'] = $relative['query'];
8724                                                 }
8725                                                 elseif ($base['query'] !== '')
8726                                                 {
8727                                                         $target['query'] = $base['query'];
8728                                                 }
8729                                         }
8730                                 }
8731                                 $target['fragment'] = $relative['fragment'];
8732                         }
8733                         else
8734                         {
8735                                 // No base URL, just return the relative URL
8736                                 $target = $relative;
8737                         }
8738                         $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8739                 }
8740                 else
8741                 {
8742                         $return = $base;
8743                 }
8744                 $return = SimplePie_Misc::normalize_url($return);
8745                 return $return;
8746         }
8747
8748         function remove_dot_segments($input)
8749         {
8750                 $output = '';
8751                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8752                 {
8753                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8754                         if (strpos($input, '../') === 0)
8755                         {
8756                                 $input = substr($input, 3);
8757                         }
8758                         elseif (strpos($input, './') === 0)
8759                         {
8760                                 $input = substr($input, 2);
8761                         }
8762                         // 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,
8763                         elseif (strpos($input, '/./') === 0)
8764                         {
8765                                 $input = substr_replace($input, '/', 0, 3);
8766                         }
8767                         elseif ($input == '/.')
8768                         {
8769                                 $input = '/';
8770                         }
8771                         // 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,
8772                         elseif (strpos($input, '/../') === 0)
8773                         {
8774                                 $input = substr_replace($input, '/', 0, 4);
8775                                 $output = substr_replace($output, '', strrpos($output, '/'));
8776                         }
8777                         elseif ($input == '/..')
8778                         {
8779                                 $input = '/';
8780                                 $output = substr_replace($output, '', strrpos($output, '/'));
8781                         }
8782                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8783                         elseif ($input == '.' || $input == '..')
8784                         {
8785                                 $input = '';
8786                         }
8787                         // 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
8788                         elseif (($pos = strpos($input, '/', 1)) !== false)
8789                         {
8790                                 $output .= substr($input, 0, $pos);
8791                                 $input = substr_replace($input, '', 0, $pos);
8792                         }
8793                         else
8794                         {
8795                                 $output .= $input;
8796                                 $input = '';
8797                         }
8798                 }
8799                 return $output . $input;
8800         }
8801
8802         function get_element($realname, $string)
8803         {
8804                 $return = array();
8805                 $name = preg_quote($realname, '/');
8806                 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8807                 {
8808                         for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8809                         {
8810                                 $return[$i]['tag'] = $realname;
8811                                 $return[$i]['full'] = $matches[$i][0][0];
8812                                 $return[$i]['offset'] = $matches[$i][0][1];
8813                                 if (strlen($matches[$i][3][0]) <= 2)
8814                                 {
8815                                         $return[$i]['self_closing'] = true;
8816                                 }
8817                                 else
8818                                 {
8819                                         $return[$i]['self_closing'] = false;
8820                                         $return[$i]['content'] = $matches[$i][4][0];
8821                                 }
8822                                 $return[$i]['attribs'] = array();
8823                                 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))
8824                                 {
8825                                         for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8826                                         {
8827                                                 if (count($attribs[$j]) == 2)
8828                                                 {
8829                                                         $attribs[$j][2] = $attribs[$j][1];
8830                                                 }
8831                                                 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8832                                         }
8833                                 }
8834                         }
8835                 }
8836                 return $return;
8837         }
8838
8839         function element_implode($element)
8840         {
8841                 $full = "<$element[tag]";
8842                 foreach ($element['attribs'] as $key => $value)
8843                 {
8844                         $key = strtolower($key);
8845                         $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8846                 }
8847                 if ($element['self_closing'])
8848                 {
8849                         $full .= ' />';
8850                 }
8851                 else
8852                 {
8853                         $full .= ">$element[content]</$element[tag]>";
8854                 }
8855                 return $full;
8856         }
8857
8858         function error($message, $level, $file, $line)
8859         {
8860                 switch ($level)
8861                 {
8862                         case E_USER_ERROR:
8863                                 $note = 'PHP Error';
8864                                 break;
8865                         case E_USER_WARNING:
8866                                 $note = 'PHP Warning';
8867                                 break;
8868                         case E_USER_NOTICE:
8869                                 $note = 'PHP Notice';
8870                                 break;
8871                         default:
8872                                 $note = 'Unknown Error';
8873                                 break;
8874                 }
8875                 error_log("$note: $message in $file on line $line", 0);
8876                 return $message;
8877         }
8878
8879         /**
8880          * If a file has been cached, retrieve and display it.
8881          *
8882          * This is most useful for caching images (get_favicon(), etc.),
8883          * however it works for all cached files.  This WILL NOT display ANY
8884          * file/image/page/whatever, but rather only display what has already
8885          * been cached by SimplePie.
8886          *
8887          * @access public
8888          * @see SimplePie::get_favicon()
8889          * @param str $identifier_url URL that is used to identify the content.
8890          * This may or may not be the actual URL of the live content.
8891          * @param str $cache_location Location of SimplePie's cache.  Defaults
8892          * to './cache'.
8893          * @param str $cache_extension The file extension that the file was
8894          * cached with.  Defaults to 'spc'.
8895          * @param str $cache_class Name of the cache-handling class being used
8896          * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
8897          * as-is unless you've overloaded the class.
8898          * @param str $cache_name_function Obsolete. Exists for backwards
8899          * compatibility reasons only.
8900          */
8901         function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8902         {
8903                 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8904
8905                 if ($file = $cache->load())
8906                 {
8907                         if (isset($file['headers']['content-type']))
8908                         {
8909                                 header('Content-type:' . $file['headers']['content-type']);
8910                         }
8911                         else
8912                         {
8913                                 header('Content-type: application/octet-stream');
8914                         }
8915                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8916                         echo $file['body'];
8917                         exit;
8918                 }
8919
8920                 die('Cached file for ' . $identifier_url . ' cannot be found.');
8921         }
8922
8923         function fix_protocol($url, $http = 1)
8924         {
8925                 $url = SimplePie_Misc::normalize_url($url);
8926                 $parsed = SimplePie_Misc::parse_url($url);
8927                 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8928                 {
8929                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8930                 }
8931
8932                 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8933                 {
8934                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8935                 }
8936
8937                 if ($http == 2 && $parsed['scheme'] !== '')
8938                 {
8939                         return "feed:$url";
8940                 }
8941                 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8942                 {
8943                         return substr_replace($url, 'podcast', 0, 4);
8944                 }
8945                 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8946                 {
8947                         return substr_replace($url, 'itpc', 0, 4);
8948                 }
8949                 else
8950                 {
8951                         return $url;
8952                 }
8953         }
8954
8955         function parse_url($url)
8956         {
8957                 static $cache = array();
8958                 if (isset($cache[$url]))
8959                 {
8960                         return $cache[$url];
8961                 }
8962                 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8963                 {
8964                         for ($i = count($match); $i <= 9; $i++)
8965                         {
8966                                 $match[$i] = '';
8967                         }
8968                         return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8969                 }
8970                 else
8971                 {
8972                         return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8973                 }
8974         }
8975
8976         function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8977         {
8978                 $return = '';
8979                 if ($scheme !== '')
8980                 {
8981                         $return .= "$scheme:";
8982                 }
8983                 if ($authority !== '')
8984                 {
8985                         $return .= "//$authority";
8986                 }
8987                 if ($path !== '')
8988                 {
8989                         $return .= $path;
8990                 }
8991                 if ($query !== '')
8992                 {
8993                         $return .= "?$query";
8994                 }
8995                 if ($fragment !== '')
8996                 {
8997                         $return .= "#$fragment";
8998                 }
8999                 return $return;
9000         }
9001
9002         function normalize_url($url)
9003         {
9004                 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9005                 $url = SimplePie_Misc::parse_url($url);
9006                 $url['scheme'] = strtolower($url['scheme']);
9007                 if ($url['authority'] !== '')
9008                 {
9009                         $url['authority'] = strtolower($url['authority']);
9010                         $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9011                 }
9012                 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9013         }
9014
9015         function percent_encoding_normalization($match)
9016         {
9017                 $integer = hexdec($match[1]);
9018                 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9019                 {
9020                         return chr($integer);
9021                 }
9022                 else
9023                 {
9024                         return strtoupper($match[0]);
9025                 }
9026         }
9027
9028         /**
9029          * Remove bad UTF-8 bytes
9030          *
9031          * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9032          * FAQ: Multilingual Forms (modified to include full ASCII range)
9033          *
9034          * @author Geoffrey Sneddon
9035          * @see http://www.w3.org/International/questions/qa-forms-utf-8
9036          * @param string $str String to remove bad UTF-8 bytes from
9037          * @return string UTF-8 string
9038          */
9039         function utf8_bad_replace($str)
9040         {
9041                 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9042                 {
9043                         return $return;
9044                 }
9045                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9046                 {
9047                         return $return;
9048                 }
9049                 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))
9050                 {
9051                         return implode("\xEF\xBF\xBD", $matches[0]);
9052                 }
9053                 elseif ($str !== '')
9054                 {
9055                         return "\xEF\xBF\xBD";
9056                 }
9057                 else
9058                 {
9059                         return '';
9060                 }
9061         }
9062
9063         /**
9064          * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9065          *
9066          * @static
9067          * @access public
9068          * @param string $string Windows-1252 encoded string
9069          * @return string UTF-8 encoded string
9070          */
9071         function windows_1252_to_utf8($string)
9072         {
9073                 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");
9074
9075                 return strtr($string, $convert_table);
9076         }
9077
9078         function change_encoding($data, $input, $output)
9079         {
9080                 $input = SimplePie_Misc::encoding($input);
9081                 $output = SimplePie_Misc::encoding($output);
9082
9083                 // We fail to fail on non US-ASCII bytes
9084                 if ($input === 'US-ASCII')
9085                 {
9086                         static $non_ascii_octects = '';
9087                         if (!$non_ascii_octects)
9088                         {
9089                                 for ($i = 0x80; $i <= 0xFF; $i++)
9090                                 {
9091                                         $non_ascii_octects .= chr($i);
9092                                 }
9093                         }
9094                         $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9095                 }
9096
9097                 // This is first, as behaviour of this is completely predictable
9098                 if ($input === 'Windows-1252' && $output === 'UTF-8')
9099                 {
9100                         return SimplePie_Misc::windows_1252_to_utf8($data);
9101                 }
9102                 // This is second, as behaviour of this varies only with PHP version
9103                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9104                 {
9105                         return $return;
9106                 }
9107                 // This is last, as behaviour of this varies with OS userland and PHP version
9108                 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9109                 {
9110                         return $return;
9111                 }
9112                 // If we can't do anything, just fail
9113                 else
9114                 {
9115                         return false;
9116                 }
9117         }
9118
9119         function encoding($charset)
9120         {
9121                 /* Character sets are case-insensitive, and also need some further
9122                 normalization in the real world (though we'll return them in the form given
9123                 in their registration). */
9124                 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9125                 {
9126                         case 'adobestandardencoding':
9127                         case 'csadobestandardencoding':
9128                                 return 'Adobe-Standard-Encoding';
9129
9130                         case 'adobesymbolencoding':
9131                         case 'cshppsmath':
9132                                 return 'Adobe-Symbol-Encoding';
9133
9134                         case 'ami1251':
9135                         case 'ami1251':
9136                         case 'amiga1251':
9137                         case 'amiga1251':
9138                                 return 'Amiga-1251';
9139
9140                         case 'ansix31101983':
9141                         case 'csat5001983':
9142                         case 'csiso99naplps':
9143                         case 'isoir99':
9144                         case 'naplps':
9145                                 return 'ANSI_X3.110-1983';
9146
9147                         case 'arabic7':
9148                         case 'asmo449':
9149                         case 'csiso89asmo449':
9150                         case 'isoir89':
9151                         case 'iso9036':
9152                                 return 'ASMO_449';
9153
9154                         case 'big5':
9155                         case 'csbig5':
9156                         case 'xxbig5':
9157                                 return 'Big5';
9158
9159                         case 'big5hkscs':
9160                                 return 'Big5-HKSCS';
9161
9162                         case 'bocu1':
9163                         case 'csbocu1':
9164                                 return 'BOCU-1';
9165
9166                         case 'brf':
9167                         case 'csbrf':
9168                                 return 'BRF';
9169
9170                         case 'bs4730':
9171                         case 'csiso4unitedkingdom':
9172                         case 'gb':
9173                         case 'isoir4':
9174                         case 'iso646gb':
9175                         case 'uk':
9176                                 return 'BS_4730';
9177
9178                         case 'bsviewdata':
9179                         case 'csiso47bsviewdata':
9180                         case 'isoir47':
9181                                 return 'BS_viewdata';
9182
9183                         case 'cesu8':
9184                         case 'cscesu8':
9185                                 return 'CESU-8';
9186
9187                         case 'ca':
9188                         case 'csa71':
9189                         case 'csaz243419851':
9190                         case 'csiso121canadian1':
9191                         case 'isoir121':
9192                         case 'iso646ca':
9193                                 return 'CSA_Z243.4-1985-1';
9194
9195                         case 'csa72':
9196                         case 'csaz243419852':
9197                         case 'csiso122canadian2':
9198                         case 'isoir122':
9199                         case 'iso646ca2':
9200                                 return 'CSA_Z243.4-1985-2';
9201
9202                         case 'csaz24341985gr':
9203                         case 'csiso123csaz24341985gr':
9204                         case 'isoir123':
9205                                 return 'CSA_Z243.4-1985-gr';
9206
9207                         case 'csiso139csn369103':
9208                         case 'csn369103':
9209                         case 'isoir139':
9210                                 return 'CSN_369103';
9211
9212                         case 'csdecmcs':
9213                         case 'dec':
9214                         case 'decmcs':
9215                                 return 'DEC-MCS';
9216
9217                         case 'csiso21german':
9218                         case 'de':
9219                         case 'din66003':
9220                         case 'isoir21':
9221                         case 'iso646de':
9222                                 return 'DIN_66003';
9223
9224                         case 'csdkus':
9225                         case 'dkus':
9226                                 return 'dk-us';
9227
9228                         case 'csiso646danish':
9229                         case 'dk':
9230                         case 'ds2089':
9231                         case 'ds2089':
9232                         case 'iso646dk':
9233                                 return 'DS_2089';
9234
9235                         case 'csibmebcdicatde':
9236                         case 'ebcdicatde':
9237                                 return 'EBCDIC-AT-DE';
9238
9239                         case 'csebcdicatdea':
9240                         case 'ebcdicatdea':
9241                                 return 'EBCDIC-AT-DE-A';
9242
9243                         case 'csebcdiccafr':
9244                         case 'ebcdiccafr':
9245                                 return 'EBCDIC-CA-FR';
9246
9247                         case 'csebcdicdkno':
9248                         case 'ebcdicdkno':
9249                                 return 'EBCDIC-DK-NO';
9250
9251                         case 'csebcdicdknoa':
9252                         case 'ebcdicdknoa':
9253                                 return 'EBCDIC-DK-NO-A';
9254
9255                         case 'csebcdices':
9256                         case 'ebcdices':
9257                                 return 'EBCDIC-ES';
9258
9259                         case 'csebcdicesa':
9260                         case 'ebcdicesa':
9261                                 return 'EBCDIC-ES-A';
9262
9263                         case 'csebcdicess':
9264                         case 'ebcdicess':
9265                                 return 'EBCDIC-ES-S';
9266
9267                         case 'csebcdicfise':
9268                         case 'ebcdicfise':
9269                                 return 'EBCDIC-FI-SE';
9270
9271                         case 'csebcdicfisea':
9272                         case 'ebcdicfisea':
9273                                 return 'EBCDIC-FI-SE-A';
9274
9275                         case 'csebcdicfr':
9276                         case 'ebcdicfr':
9277                                 return 'EBCDIC-FR';
9278
9279                         case 'csebcdicit':
9280                         case 'ebcdicit':
9281                                 return 'EBCDIC-IT';
9282
9283                         case 'csebcdicpt':
9284                         case 'ebcdicpt':
9285                                 return 'EBCDIC-PT';
9286
9287                         case 'csebcdicuk':
9288                         case 'ebcdicuk':
9289                                 return 'EBCDIC-UK';
9290
9291                         case 'csebcdicus':
9292                         case 'ebcdicus':
9293                                 return 'EBCDIC-US';
9294
9295                         case 'csiso111ecmacyrillic':
9296                         case 'ecmacyrillic':
9297                         case 'isoir111':
9298                         case 'koi8e':
9299                                 return 'ECMA-cyrillic';
9300
9301                         case 'csiso17spanish':
9302                         case 'es':
9303                         case 'isoir17':
9304                         case 'iso646es':
9305                                 return 'ES';
9306
9307                         case 'csiso85spanish2':
9308                         case 'es2':
9309                         case 'isoir85':
9310                         case 'iso646es2':
9311                                 return 'ES2';
9312
9313                         case 'cseucfixwidjapanese':
9314                         case 'extendedunixcodefixedwidthforjapanese':
9315                                 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9316
9317                         case 'cseucpkdfmtjapanese':
9318                         case 'eucjp':
9319                         case 'extendedunixcodepackedformatforjapanese':
9320                                 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9321
9322                         case 'gb18030':
9323                                 return 'GB18030';
9324
9325                         case 'cp936':
9326                         case 'gbk':
9327                         case 'ms936':
9328                         case 'windows936':
9329                         case 'csgb2312':
9330                         case 'gb2312':
9331                         case 'chinese':
9332                         case 'csiso58gb231280':
9333                         case 'gb231280':
9334                         case 'isoir58':
9335                                 return 'GBK';
9336
9337                         case 'cn':
9338                         case 'csiso57gb1988':
9339                         case 'gb198880':
9340                         case 'isoir57':
9341                         case 'iso646cn':
9342                                 return 'GB_1988-80';
9343
9344                         case 'csiso153gost1976874':
9345                         case 'gost1976874':
9346                         case 'isoir153':
9347                         case 'stsev35888':
9348                                 return 'GOST_19768-74';
9349
9350                         case 'csiso150':
9351                         case 'csiso150greekccitt':
9352                         case 'greekccitt':
9353                         case 'isoir150':
9354                                 return 'greek-ccitt';
9355
9356                         case 'csiso88greek7':
9357                         case 'greek7':
9358                         case 'isoir88':
9359                                 return 'greek7';
9360
9361                         case 'csiso18greek7old':
9362                         case 'greek7old':
9363                         case 'isoir18':
9364                                 return 'greek7-old';
9365
9366                         case 'cshpdesktop':
9367                         case 'hpdesktop':
9368                                 return 'HP-DeskTop';
9369
9370                         case 'cshplegal':
9371                         case 'hplegal':
9372                                 return 'HP-Legal';
9373
9374                         case 'cshpmath8':
9375                         case 'hpmath8':
9376                                 return 'HP-Math8';
9377
9378                         case 'cshppifont':
9379                         case 'hppifont':
9380                                 return 'HP-Pi-font';
9381
9382                         case 'cshproman8':
9383                         case 'hproman8':
9384                         case 'r8':
9385                         case 'roman8':
9386                                 return 'hp-roman8';
9387
9388                         case 'hzgb2312':
9389                                 return 'HZ-GB-2312';
9390
9391                         case 'csibmsymbols':
9392                         case 'ibmsymbols':
9393                                 return 'IBM-Symbols';
9394
9395                         case 'csibmthai':
9396                         case 'ibmthai':
9397                                 return 'IBM-Thai';
9398
9399                         case 'ccsid00858':
9400                         case 'cp00858':
9401                         case 'ibm00858':
9402                         case 'pcmultilingual850euro':
9403                                 return 'IBM00858';
9404
9405                         case 'ccsid00924':
9406                         case 'cp00924':
9407                         case 'ebcdiclatin9euro':
9408                         case 'ibm00924':
9409                                 return 'IBM00924';
9410
9411                         case 'ccsid01140':
9412                         case 'cp01140':
9413                         case 'ebcdicus37euro':
9414                         case 'ibm01140':
9415                                 return 'IBM01140';
9416
9417                         case 'ccsid01141':
9418                         case 'cp01141':
9419                         case 'ebcdicde273euro':
9420                         case 'ibm01141':
9421                                 return 'IBM01141';
9422
9423                         case 'ccsid01142':
9424                         case 'cp01142':
9425                         case 'ebcdicdk277euro':
9426                         case 'ebcdicno277euro':
9427                         case 'ibm01142':
9428                                 return 'IBM01142';
9429
9430                         case 'ccsid01143':
9431                         case 'cp01143':
9432                         case 'ebcdicfi278euro':
9433                         case 'ebcdicse278euro':
9434                         case 'ibm01143':
9435                                 return 'IBM01143';
9436
9437                         case 'ccsid01144':
9438                         case 'cp01144':
9439                         case 'ebcdicit280euro':
9440                         case 'ibm01144':
9441                                 return 'IBM01144';
9442
9443                         case 'ccsid01145':
9444                         case 'cp01145':
9445                         case 'ebcdices284euro':
9446                         case 'ibm01145':
9447                                 return 'IBM01145';
9448
9449                         case 'ccsid01146':
9450                         case 'cp01146':
9451                         case 'ebcdicgb285euro':
9452                         case 'ibm01146':
9453                                 return 'IBM01146';
9454
9455                         case 'ccsid01147':
9456                         case 'cp01147':
9457                         case 'ebcdicfr297euro':
9458                         case 'ibm01147':
9459                                 return 'IBM01147';
9460
9461                         case 'ccsid01148':
9462                         case 'cp01148':
9463                         case 'ebcdicinternational500euro':
9464                         case 'ibm01148':
9465                                 return 'IBM01148';
9466
9467                         case 'ccsid01149':
9468                         case 'cp01149':
9469                         case 'ebcdicis871euro':
9470                         case 'ibm01149':
9471                                 return 'IBM01149';
9472
9473                         case 'cp037':
9474                         case 'csibm037':
9475                         case 'ebcdiccpca':
9476                         case 'ebcdiccpnl':
9477                         case 'ebcdiccpus':
9478                         case 'ebcdiccpwt':
9479                         case 'ibm037':
9480                                 return 'IBM037';
9481
9482                         case 'cp038':
9483                         case 'csibm038':
9484                         case 'ebcdicint':
9485                         case 'ibm038':
9486                                 return 'IBM038';
9487
9488                         case 'cp273':
9489                         case 'csibm273':
9490                         case 'ibm273':
9491                                 return 'IBM273';
9492
9493                         case 'cp274':
9494                         case 'csibm274':
9495                         case 'ebcdicbe':
9496                         case 'ibm274':
9497                                 return 'IBM274';
9498
9499                         case 'cp275':
9500                         case 'csibm275':
9501                         case 'ebcdicbr':
9502                         case 'ibm275':
9503                                 return 'IBM275';
9504
9505                         case 'csibm277':
9506                         case 'ebcdiccpdk':
9507                         case 'ebcdiccpno':
9508                         case 'ibm277':
9509                                 return 'IBM277';
9510
9511                         case 'cp278':
9512                         case 'csibm278':
9513                         case 'ebcdiccpfi':
9514                         case 'ebcdiccpse':
9515                         case 'ibm278':
9516                                 return 'IBM278';
9517
9518                         case 'cp280':
9519                         case 'csibm280':
9520                         case 'ebcdiccpit':
9521                         case 'ibm280':
9522                                 return 'IBM280';
9523
9524                         case 'cp281':
9525                         case 'csibm281':
9526                         case 'ebcdicjpe':
9527                         case 'ibm281':
9528                                 return 'IBM281';
9529
9530                         case 'cp284':
9531                         case 'csibm284':
9532                         case 'ebcdiccpes':
9533                         case 'ibm284':
9534                                 return 'IBM284';
9535
9536                         case 'cp285':
9537                         case 'csibm285':
9538                         case 'ebcdiccpgb':
9539                         case 'ibm285':
9540                                 return 'IBM285';
9541
9542                         case 'cp290':
9543                         case 'csibm290':
9544                         case 'ebcdicjpkana':
9545                         case 'ibm290':
9546                                 return 'IBM290';
9547
9548                         case 'cp297':
9549                         case 'csibm297':
9550                         case 'ebcdiccpfr':
9551                         case 'ibm297':
9552                                 return 'IBM297';
9553
9554                         case 'cp420':
9555                         case 'csibm420':
9556                         case 'ebcdiccpar1':
9557                         case 'ibm420':
9558                                 return 'IBM420';
9559
9560                         case 'cp423':
9561                         case 'csibm423':
9562                         case 'ebcdiccpgr':
9563                         case 'ibm423':
9564                                 return 'IBM423';
9565
9566                         case 'cp424':
9567                         case 'csibm424':
9568                         case 'ebcdiccphe':
9569                         case 'ibm424':
9570                                 return 'IBM424';
9571
9572                         case '437':
9573                         case 'cp437':
9574                         case 'cspc8codepage437':
9575                         case 'ibm437':
9576                                 return 'IBM437';
9577
9578                         case 'cp500':
9579                         case 'csibm500':
9580                         case 'ebcdiccpbe':
9581                         case 'ebcdiccpch':
9582                         case 'ibm500':
9583                                 return 'IBM500';
9584
9585                         case 'cp775':
9586                         case 'cspc775baltic':
9587                         case 'ibm775':
9588                                 return 'IBM775';
9589
9590                         case '850':
9591                         case 'cp850':
9592                         case 'cspc850multilingual':
9593                         case 'ibm850':
9594                                 return 'IBM850';
9595
9596                         case '851':
9597                         case 'cp851':
9598                         case 'csibm851':
9599                         case 'ibm851':
9600                                 return 'IBM851';
9601
9602                         case '852':
9603                         case 'cp852':
9604                         case 'cspcp852':
9605                         case 'ibm852':
9606                                 return 'IBM852';
9607
9608                         case '855':
9609                         case 'cp855':
9610                         case 'csibm855':
9611                         case 'ibm855':
9612                                 return 'IBM855';
9613
9614                         case '857':
9615                         case 'cp857':
9616                         case 'csibm857':
9617                         case 'ibm857':
9618                                 return 'IBM857';
9619
9620                         case '860':
9621                         case 'cp860':
9622                         case 'csibm860':
9623                         case 'ibm860':
9624                                 return 'IBM860';
9625
9626                         case '861':
9627                         case 'cpis':
9628                         case 'cp861':
9629                         case 'csibm861':
9630                         case 'ibm861':
9631                                 return 'IBM861';
9632
9633                         case '862':
9634                         case 'cp862':
9635                         case 'cspc862latinhebrew':
9636                         case 'ibm862':
9637                                 return 'IBM862';
9638
9639                         case '863':
9640                         case 'cp863':
9641                         case 'csibm863':
9642                         case 'ibm863':
9643                                 return 'IBM863';
9644
9645                         case 'cp864':
9646                         case 'csibm864':
9647                         case 'ibm864':
9648                                 return 'IBM864';
9649
9650                         case '865':
9651                         case 'cp865':
9652                         case 'csibm865':
9653                         case 'ibm865':
9654                                 return 'IBM865';
9655
9656                         case '866':
9657                         case 'cp866':
9658                         case 'csibm866':
9659                         case 'ibm866':
9660                                 return 'IBM866';
9661
9662                         case 'cpar':
9663                         case 'cp868':
9664                         case 'csibm868':
9665                         case 'ibm868':
9666                                 return 'IBM868';
9667
9668                         case '869':
9669                         case 'cpgr':
9670                         case 'cp869':
9671                         case 'csibm869':
9672                         case 'ibm869':
9673                                 return 'IBM869';
9674
9675                         case 'cp870':
9676                         case 'csibm870':
9677                         case 'ebcdiccproece':
9678                         case 'ebcdiccpyu':
9679                         case 'ibm870':
9680                                 return 'IBM870';
9681
9682                         case 'cp871':
9683                         case 'csibm871':
9684                         case 'ebcdiccpis':
9685                         case 'ibm871':
9686                                 return 'IBM871';
9687
9688                         case 'cp880':
9689                         case 'csibm880':
9690                         case 'ebcdiccyrillic':
9691                         case 'ibm880':
9692                                 return 'IBM880';
9693
9694                         case 'cp891':
9695                         case 'csibm891':
9696                         case 'ibm891':
9697                                 return 'IBM891';
9698
9699                         case 'cp903':
9700                         case 'csibm903':
9701                         case 'ibm903':
9702                                 return 'IBM903';
9703
9704                         case '904':
9705                         case 'cp904':
9706                         case 'csibbm904':
9707                         case 'ibm904':
9708                                 return 'IBM904';
9709
9710                         case 'cp905':
9711                         case 'csibm905':
9712                         case 'ebcdiccptr':
9713                         case 'ibm905':
9714                                 return 'IBM905';
9715
9716                         case 'cp918':
9717                         case 'csibm918':
9718                         case 'ebcdiccpar2':
9719                         case 'ibm918':
9720                                 return 'IBM918';
9721
9722                         case 'cp1026':
9723                         case 'csibm1026':
9724                         case 'ibm1026':
9725                                 return 'IBM1026';
9726
9727                         case 'ibm1047':
9728                         case 'ibm1047':
9729                                 return 'IBM1047';
9730
9731                         case 'csiso143iecp271':
9732                         case 'iecp271':
9733                         case 'isoir143':
9734                                 return 'IEC_P27-1';
9735
9736                         case 'csiso49inis':
9737                         case 'inis':
9738                         case 'isoir49':
9739                                 return 'INIS';
9740
9741                         case 'csiso50inis8':
9742                         case 'inis8':
9743                         case 'isoir50':
9744                                 return 'INIS-8';
9745
9746                         case 'csiso51iniscyrillic':
9747                         case 'iniscyrillic':
9748                         case 'isoir51':
9749                                 return 'INIS-cyrillic';
9750
9751                         case 'csinvariant':
9752                         case 'invariant':
9753                                 return 'INVARIANT';
9754
9755                         case 'iso2022cn':
9756                                 return 'ISO-2022-CN';
9757
9758                         case 'iso2022cnext':
9759                                 return 'ISO-2022-CN-EXT';
9760
9761                         case 'csiso2022jp':
9762                         case 'iso2022jp':
9763                                 return 'ISO-2022-JP';
9764
9765                         case 'csiso2022jp2':
9766                         case 'iso2022jp2':
9767                                 return 'ISO-2022-JP-2';
9768
9769                         case 'csiso2022kr':
9770                         case 'iso2022kr':
9771                                 return 'ISO-2022-KR';
9772
9773                         case 'cswindows30latin1':
9774                         case 'iso88591windows30latin1':
9775                                 return 'ISO-8859-1-Windows-3.0-Latin-1';
9776
9777                         case 'cswindows31latin1':
9778                         case 'iso88591windows31latin1':
9779                                 return 'ISO-8859-1-Windows-3.1-Latin-1';
9780
9781                         case 'csisolatin2':
9782                         case 'iso88592':
9783                         case 'isoir101':
9784                         case 'iso88592':
9785                         case 'iso885921987':
9786                         case 'l2':
9787                         case 'latin2':
9788                                 return 'ISO-8859-2';
9789
9790                         case 'cswindows31latin2':
9791                         case 'iso88592windowslatin2':
9792                                 return 'ISO-8859-2-Windows-Latin-2';
9793
9794                         case 'csisolatin3':
9795                         case 'iso88593':
9796                         case 'isoir109':
9797                         case 'iso88593':
9798                         case 'iso885931988':
9799                         case 'l3':
9800                         case 'latin3':
9801                                 return 'ISO-8859-3';
9802
9803                         case 'csisolatin4':
9804                         case 'iso88594':
9805                         case 'isoir110':
9806                         case 'iso88594':
9807                         case 'iso885941988':
9808                         case 'l4':
9809                         case 'latin4':
9810                                 return 'ISO-8859-4';
9811
9812                         case 'csisolatincyrillic':
9813                         case 'cyrillic':
9814                         case 'iso88595':
9815                         case 'isoir144':
9816                         case 'iso88595':
9817                         case 'iso885951988':
9818                                 return 'ISO-8859-5';
9819
9820                         case 'arabic':
9821                         case 'asmo708':
9822                         case 'csisolatinarabic':
9823                         case 'ecma114':
9824                         case 'iso88596':
9825                         case 'isoir127':
9826                         case 'iso88596':
9827                         case 'iso885961987':
9828                                 return 'ISO-8859-6';
9829
9830                         case 'csiso88596e':
9831                         case 'iso88596e':
9832                         case 'iso88596e':
9833                                 return 'ISO-8859-6-E';
9834
9835                         case 'csiso88596i':
9836                         case 'iso88596i':
9837                         case 'iso88596i':
9838                                 return 'ISO-8859-6-I';
9839
9840                         case 'csisolatingreek':
9841                         case 'ecma118':
9842                         case 'elot928':
9843                         case 'greek':
9844                         case 'greek8':
9845                         case 'iso88597':
9846                         case 'isoir126':
9847                         case 'iso88597':
9848                         case 'iso885971987':
9849                                 return 'ISO-8859-7';
9850
9851                         case 'csisolatinhebrew':
9852                         case 'hebrew':
9853                         case 'iso88598':
9854                         case 'isoir138':
9855                         case 'iso88598':
9856                         case 'iso885981988':
9857                                 return 'ISO-8859-8';
9858
9859                         case 'csiso88598e':
9860                         case 'iso88598e':
9861                         case 'iso88598e':
9862                                 return 'ISO-8859-8-E';
9863
9864                         case 'csiso88598i':
9865                         case 'iso88598i':
9866                         case 'iso88598i':
9867                                 return 'ISO-8859-8-I';
9868
9869                         case 'cswindows31latin5':
9870                         case 'iso88599windowslatin5':
9871                                 return 'ISO-8859-9-Windows-Latin-5';
9872
9873                         case 'csisolatin6':
9874                         case 'iso885910':
9875                         case 'isoir157':
9876                         case 'iso8859101992':
9877                         case 'l6':
9878                         case 'latin6':
9879                                 return 'ISO-8859-10';
9880
9881                         case 'iso885913':
9882                                 return 'ISO-8859-13';
9883
9884                         case 'iso885914':
9885                         case 'isoceltic':
9886                         case 'isoir199':
9887                         case 'iso885914':
9888                         case 'iso8859141998':
9889                         case 'l8':
9890                         case 'latin8':
9891                                 return 'ISO-8859-14';
9892
9893                         case 'iso885915':
9894                         case 'iso885915':
9895                         case 'latin9':
9896                                 return 'ISO-8859-15';
9897
9898                         case 'iso885916':
9899                         case 'isoir226':
9900                         case 'iso885916':
9901                         case 'iso8859162001':
9902                         case 'l10':
9903                         case 'latin10':
9904                                 return 'ISO-8859-16';
9905
9906                         case 'iso10646j1':
9907                                 return 'ISO-10646-J-1';
9908
9909                         case 'csunicode':
9910                         case 'iso10646ucs2':
9911                                 return 'ISO-10646-UCS-2';
9912
9913                         case 'csucs4':
9914                         case 'iso10646ucs4':
9915                                 return 'ISO-10646-UCS-4';
9916
9917                         case 'csunicodeascii':
9918                         case 'iso10646ucsbasic':
9919                                 return 'ISO-10646-UCS-Basic';
9920
9921                         case 'csunicodelatin1':
9922                         case 'iso10646':
9923                         case 'iso10646unicodelatin1':
9924                                 return 'ISO-10646-Unicode-Latin1';
9925
9926                         case 'csiso10646utf1':
9927                         case 'iso10646utf1':
9928                                 return 'ISO-10646-UTF-1';
9929
9930                         case 'csiso115481':
9931                         case 'iso115481':
9932                         case 'iso115481':
9933                         case 'isotr115481':
9934                                 return 'ISO-11548-1';
9935
9936                         case 'csiso90':
9937                         case 'isoir90':
9938                                 return 'iso-ir-90';
9939
9940                         case 'csunicodeibm1261':
9941                         case 'isounicodeibm1261':
9942                                 return 'ISO-Unicode-IBM-1261';
9943
9944                         case 'csunicodeibm1264':
9945                         case 'isounicodeibm1264':
9946                                 return 'ISO-Unicode-IBM-1264';
9947
9948                         case 'csunicodeibm1265':
9949                         case 'isounicodeibm1265':
9950                                 return 'ISO-Unicode-IBM-1265';
9951
9952                         case 'csunicodeibm1268':
9953                         case 'isounicodeibm1268':
9954                                 return 'ISO-Unicode-IBM-1268';
9955
9956                         case 'csunicodeibm1276':
9957                         case 'isounicodeibm1276':
9958                                 return 'ISO-Unicode-IBM-1276';
9959
9960                         case 'csiso646basic1983':
9961                         case 'iso646basic1983':
9962                         case 'ref':
9963                                 return 'ISO_646.basic:1983';
9964
9965                         case 'csiso2intlrefversion':
9966                         case 'irv':
9967                         case 'isoir2':
9968                         case 'iso646irv1983':
9969                                 return 'ISO_646.irv:1983';
9970
9971                         case 'csiso2033':
9972                         case 'e13b':
9973                         case 'isoir98':
9974                         case 'iso20331983':
9975                                 return 'ISO_2033-1983';
9976
9977                         case 'csiso5427cyrillic':
9978                         case 'isoir37':
9979                         case 'iso5427':
9980                                 return 'ISO_5427';
9981
9982                         case 'isoir54':
9983                         case 'iso5427cyrillic1981':
9984                         case 'iso54271981':
9985                                 return 'ISO_5427:1981';
9986
9987                         case 'csiso5428greek':
9988                         case 'isoir55':
9989                         case 'iso54281980':
9990                                 return 'ISO_5428:1980';
9991
9992                         case 'csiso6937add':
9993                         case 'isoir152':
9994                         case 'iso6937225':
9995                                 return 'ISO_6937-2-25';
9996
9997                         case 'csisotextcomm':
9998                         case 'isoir142':
9999                         case 'iso69372add':
10000                                 return 'ISO_6937-2-add';
10001
10002                         case 'csiso8859supp':
10003                         case 'isoir154':
10004                         case 'iso8859supp':
10005                         case 'latin125':
10006                                 return 'ISO_8859-supp';
10007
10008                         case 'csiso10367box':
10009                         case 'isoir155':
10010                         case 'iso10367box':
10011                                 return 'ISO_10367-box';
10012
10013                         case 'csiso15italian':
10014                         case 'isoir15':
10015                         case 'iso646it':
10016                         case 'it':
10017                                 return 'IT';
10018
10019                         case 'csiso13jisc6220jp':
10020                         case 'isoir13':
10021                         case 'jisc62201969':
10022                         case 'jisc62201969jp':
10023                         case 'katakana':
10024                         case 'x02017':
10025                                 return 'JIS_C6220-1969-jp';
10026
10027                         case 'csiso14jisc6220ro':
10028                         case 'isoir14':
10029                         case 'iso646jp':
10030                         case 'jisc62201969ro':
10031                         case 'jp':
10032                                 return 'JIS_C6220-1969-ro';
10033
10034                         case 'csiso42jisc62261978':
10035                         case 'isoir42':
10036                         case 'jisc62261978':
10037                                 return 'JIS_C6226-1978';
10038
10039                         case 'csiso87jisx0208':
10040                         case 'isoir87':
10041                         case 'jisc62261983':
10042                         case 'jisx02081983':
10043                         case 'x0208':
10044                                 return 'JIS_C6226-1983';
10045
10046                         case 'csiso91jisc62291984a':
10047                         case 'isoir91':
10048                         case 'jisc62291984a':
10049                         case 'jpocra':
10050                                 return 'JIS_C6229-1984-a';
10051
10052                         case 'csiso92jisc62991984b':
10053                         case 'isoir92':
10054                         case 'iso646jpocrb':
10055                         case 'jisc62291984b':
10056                         case 'jpocrb':
10057                                 return 'JIS_C6229-1984-b';
10058
10059                         case 'csiso93jis62291984badd':
10060                         case 'isoir93':
10061                         case 'jisc62291984badd':
10062                         case 'jpocrbadd':
10063                                 return 'JIS_C6229-1984-b-add';
10064
10065                         case 'csiso94jis62291984hand':
10066                         case 'isoir94':
10067                         case 'jisc62291984hand':
10068                         case 'jpocrhand':
10069                                 return 'JIS_C6229-1984-hand';
10070
10071                         case 'csiso95jis62291984handadd':
10072                         case 'isoir95':
10073                         case 'jisc62291984handadd':
10074                         case 'jpocrhandadd':
10075                                 return 'JIS_C6229-1984-hand-add';
10076
10077                         case 'csiso96jisc62291984kana':
10078                         case 'isoir96':
10079                         case 'jisc62291984kana':
10080                                 return 'JIS_C6229-1984-kana';
10081
10082                         case 'csjisencoding':
10083                         case 'jisencoding':
10084                                 return 'JIS_Encoding';
10085
10086                         case 'cshalfwidthkatakana':
10087                         case 'jisx0201':
10088                         case 'x0201':
10089                                 return 'JIS_X0201';
10090
10091                         case 'csiso159jisx02121990':
10092                         case 'isoir159':
10093                         case 'jisx02121990':
10094                         case 'x0212':
10095                                 return 'JIS_X0212-1990';
10096
10097                         case 'csiso141jusib1002':
10098                         case 'isoir141':
10099                         case 'iso646yu':
10100                         case 'js':
10101                         case 'jusib1002':
10102                         case 'yu':
10103                                 return 'JUS_I.B1.002';
10104
10105                         case 'csiso147macedonian':
10106                         case 'isoir147':
10107                         case 'jusib1003mac':
10108                         case 'macedonian':
10109                                 return 'JUS_I.B1.003-mac';
10110
10111                         case 'csiso146serbian':
10112                         case 'isoir146':
10113                         case 'jusib1003serb':
10114                         case 'serbian':
10115                                 return 'JUS_I.B1.003-serb';
10116
10117                         case 'koi7switched':
10118                                 return 'KOI7-switched';
10119
10120                         case 'cskoi8r':
10121                         case 'koi8r':
10122                                 return 'KOI8-R';
10123
10124                         case 'koi8u':
10125                                 return 'KOI8-U';
10126
10127                         case 'csksc5636':
10128                         case 'iso646kr':
10129                         case 'ksc5636':
10130                                 return 'KSC5636';
10131
10132                         case 'cskz1048':
10133                         case 'kz1048':
10134                         case 'rk1048':
10135                         case 'strk10482002':
10136                                 return 'KZ-1048';
10137
10138                         case 'csiso19latingreek':
10139                         case 'isoir19':
10140                         case 'latingreek':
10141                                 return 'latin-greek';
10142
10143                         case 'csiso27latingreek1':
10144                         case 'isoir27':
10145                         case 'latingreek1':
10146                                 return 'Latin-greek-1';
10147
10148                         case 'csiso158lap':
10149                         case 'isoir158':
10150                         case 'lap':
10151                         case 'latinlap':
10152                                 return 'latin-lap';
10153
10154                         case 'csmacintosh':
10155                         case 'mac':
10156                         case 'macintosh':
10157                                 return 'macintosh';
10158
10159                         case 'csmicrosoftpublishing':
10160                         case 'microsoftpublishing':
10161                                 return 'Microsoft-Publishing';
10162
10163                         case 'csmnem':
10164                         case 'mnem':
10165                                 return 'MNEM';
10166
10167                         case 'csmnemonic':
10168                         case 'mnemonic':
10169                                 return 'MNEMONIC';
10170
10171                         case 'csiso86hungarian':
10172                         case 'hu':
10173                         case 'isoir86':
10174                         case 'iso646hu':
10175                         case 'msz77953':
10176                                 return 'MSZ_7795.3';
10177
10178                         case 'csnatsdano':
10179                         case 'isoir91':
10180                         case 'natsdano':
10181                                 return 'NATS-DANO';
10182
10183                         case 'csnatsdanoadd':
10184                         case 'isoir92':
10185                         case 'natsdanoadd':
10186                                 return 'NATS-DANO-ADD';
10187
10188                         case 'csnatssefi':
10189                         case 'isoir81':
10190                         case 'natssefi':
10191                                 return 'NATS-SEFI';
10192
10193                         case 'csnatssefiadd':
10194                         case 'isoir82':
10195                         case 'natssefiadd':
10196                                 return 'NATS-SEFI-ADD';
10197
10198                         case 'csiso151cuba':
10199                         case 'cuba':
10200                         case 'isoir151':
10201                         case 'iso646cu':
10202                         case 'ncnc001081':
10203                                 return 'NC_NC00-10:81';
10204
10205                         case 'csiso69french':
10206                         case 'fr':
10207                         case 'isoir69':
10208                         case 'iso646fr':
10209                         case 'nfz62010':
10210                                 return 'NF_Z_62-010';
10211
10212                         case 'csiso25french':
10213                         case 'isoir25':
10214                         case 'iso646fr1':
10215                         case 'nfz620101973':
10216                                 return 'NF_Z_62-010_(1973)';
10217
10218                         case 'csiso60danishnorwegian':
10219                         case 'csiso60norwegian1':
10220                         case 'isoir60':
10221                         case 'iso646no':
10222                         case 'no':
10223                         case 'ns45511':
10224                                 return 'NS_4551-1';
10225
10226                         case 'csiso61norwegian2':
10227                         case 'isoir61':
10228                         case 'iso646no2':
10229                         case 'no2':
10230                         case 'ns45512':
10231                                 return 'NS_4551-2';
10232
10233                         case 'osdebcdicdf03irv':
10234                                 return 'OSD_EBCDIC_DF03_IRV';
10235
10236                         case 'osdebcdicdf041':
10237                                 return 'OSD_EBCDIC_DF04_1';
10238
10239                         case 'osdebcdicdf0415':
10240                                 return 'OSD_EBCDIC_DF04_15';
10241
10242                         case 'cspc8danishnorwegian':
10243                         case 'pc8danishnorwegian':
10244                                 return 'PC8-Danish-Norwegian';
10245
10246                         case 'cspc8turkish':
10247                         case 'pc8turkish':
10248                                 return 'PC8-Turkish';
10249
10250                         case 'csiso16portuguese':
10251                         case 'isoir16':
10252                         case 'iso646pt':
10253                         case 'pt':
10254                                 return 'PT';
10255
10256                         case 'csiso84portuguese2':
10257                         case 'isoir84':
10258                         case 'iso646pt2':
10259                         case 'pt2':
10260                                 return 'PT2';
10261
10262                         case 'cp154':
10263                         case 'csptcp154':
10264                         case 'cyrillicasian':
10265                         case 'pt154':
10266                         case 'ptcp154':
10267                                 return 'PTCP154';
10268
10269                         case 'scsu':
10270                                 return 'SCSU';
10271
10272                         case 'csiso10swedish':
10273                         case 'fi':
10274                         case 'isoir10':
10275                         case 'iso646fi':
10276                         case 'iso646se':
10277                         case 'se':
10278                         case 'sen850200b':
10279                                 return 'SEN_850200_B';
10280
10281                         case 'csiso11swedishfornames':
10282                         case 'isoir11':
10283                         case 'iso646se2':
10284                         case 'se2':
10285                         case 'sen850200c':
10286                                 return 'SEN_850200_C';
10287
10288                         case 'csshiftjis':
10289                         case 'mskanji':
10290                         case 'shiftjis':
10291                                 return 'Shift_JIS';
10292
10293                         case 'csiso102t617bit':
10294                         case 'isoir102':
10295                         case 't617bit':
10296                                 return 'T.61-7bit';
10297
10298                         case 'csiso103t618bit':
10299                         case 'isoir103':
10300                         case 't61':
10301                         case 't618bit':
10302                                 return 'T.61-8bit';
10303
10304                         case 'csiso128t101g2':
10305                         case 'isoir128':
10306                         case 't101g2':
10307                                 return 'T.101-G2';
10308
10309                         case 'cstscii':
10310                         case 'tscii':
10311                                 return 'TSCII';
10312
10313                         case 'csunicode11':
10314                         case 'unicode11':
10315                                 return 'UNICODE-1-1';
10316
10317                         case 'csunicode11utf7':
10318                         case 'unicode11utf7':
10319                                 return 'UNICODE-1-1-UTF-7';
10320
10321                         case 'csunknown8bit':
10322                         case 'unknown8bit':
10323                                 return 'UNKNOWN-8BIT';
10324
10325                         case 'ansix341968':
10326                         case 'ansix341986':
10327                         case 'ascii':
10328                         case 'cp367':
10329                         case 'csascii':
10330                         case 'ibm367':
10331                         case 'isoir6':
10332                         case 'iso646us':
10333                         case 'iso646irv1991':
10334                         case 'us':
10335                         case 'usascii':
10336                                 return 'US-ASCII';
10337
10338                         case 'csusdk':
10339                         case 'usdk':
10340                                 return 'us-dk';
10341
10342                         case 'utf7':
10343                                 return 'UTF-7';
10344
10345                         case 'utf8':
10346                                 return 'UTF-8';
10347
10348                         case 'utf16':
10349                                 return 'UTF-16';
10350
10351                         case 'utf16be':
10352                                 return 'UTF-16BE';
10353
10354                         case 'utf16le':
10355                                 return 'UTF-16LE';
10356
10357                         case 'utf32':
10358                                 return 'UTF-32';
10359
10360                         case 'utf32be':
10361                                 return 'UTF-32BE';
10362
10363                         case 'utf32le':
10364                                 return 'UTF-32LE';
10365
10366                         case 'csventurainternational':
10367                         case 'venturainternational':
10368                                 return 'Ventura-International';
10369
10370                         case 'csventuramath':
10371                         case 'venturamath':
10372                                 return 'Ventura-Math';
10373
10374                         case 'csventuraus':
10375                         case 'venturaus':
10376                                 return 'Ventura-US';
10377
10378                         case 'csiso70videotexsupp1':
10379                         case 'isoir70':
10380                         case 'videotexsuppl':
10381                                 return 'videotex-suppl';
10382
10383                         case 'csviqr':
10384                         case 'viqr':
10385                                 return 'VIQR';
10386
10387                         case 'csviscii':
10388                         case 'viscii':
10389                                 return 'VISCII';
10390
10391                         case 'cswindows31j':
10392                         case 'windows31j':
10393                                 return 'Windows-31J';
10394
10395                         case 'iso885911':
10396                         case 'tis620':
10397                                 return 'Windows-874';
10398
10399                         case 'cseuckr':
10400                         case 'euckr':
10401                         case 'windows949':
10402                         case 'csksc56011987':
10403                         case 'isoir149':
10404                         case 'korean':
10405                         case 'ksc5601':
10406                         case 'ksc56011987':
10407                         case 'ksc56011989':
10408                                 return 'Windows-949';
10409
10410                         case 'windows1250':
10411                                 return 'windows-1250';
10412
10413                         case 'windows1251':
10414                                 return 'windows-1251';
10415
10416                         case 'cp819':
10417                         case 'csisolatin1':
10418                         case 'ibm819':
10419                         case 'iso88591':
10420                         case 'isoir100':
10421                         case 'iso885911987':
10422                         case 'l1':
10423                         case 'latin1':
10424                         case 'windows1252':
10425                                 return 'Windows-1252';
10426
10427                         case 'windows1252':
10428                                 return 'windows-1252';
10429
10430                         case 'windows1253':
10431                                 return 'windows-1253';
10432
10433                         case 'csisolatin5':
10434                         case 'iso88599':
10435                         case 'isoir148':
10436                         case 'iso885991989':
10437                         case 'l5':
10438                         case 'latin5':
10439                         case 'windows1254':
10440                                 return 'Windows-1254';
10441
10442                         case 'windows1254':
10443                                 return 'windows-1254';
10444
10445                         case 'windows1255':
10446                                 return 'windows-1255';
10447
10448                         case 'windows1256':
10449                                 return 'windows-1256';
10450
10451                         case 'windows1257':
10452                                 return 'windows-1257';
10453
10454                         case 'windows1258':
10455                                 return 'windows-1258';
10456
10457                         default:
10458                                 return $charset;
10459                 }
10460         }
10461
10462         function get_curl_version()
10463         {
10464                 if (is_array($curl = curl_version()))
10465                 {
10466                         $curl = $curl['version'];
10467                 }
10468                 elseif (substr($curl, 0, 5) == 'curl/')
10469                 {
10470                         $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10471                 }
10472                 elseif (substr($curl, 0, 8) == 'libcurl/')
10473                 {
10474                         $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10475                 }
10476                 else
10477                 {
10478                         $curl = 0;
10479                 }
10480                 return $curl;
10481         }
10482
10483         function is_subclass_of($class1, $class2)
10484         {
10485                 if (func_num_args() != 2)
10486                 {
10487                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10488                 }
10489                 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10490                 {
10491                         return is_subclass_of($class1, $class2);
10492                 }
10493                 elseif (is_string($class1) && is_string($class2))
10494                 {
10495                         if (class_exists($class1))
10496                         {
10497                                 if (class_exists($class2))
10498                                 {
10499                                         $class2 = strtolower($class2);
10500                                         while ($class1 = strtolower(get_parent_class($class1)))
10501                                         {
10502                                                 if ($class1 == $class2)
10503                                                 {
10504                                                         return true;
10505                                                 }
10506                                         }
10507                                 }
10508                         }
10509                         else
10510                         {
10511                                 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10512                         }
10513                 }
10514                 return false;
10515         }
10516
10517         /**
10518          * Strip HTML comments
10519          *
10520          * @access public
10521          * @param string $data Data to strip comments from
10522          * @return string Comment stripped string
10523          */
10524         function strip_comments($data)
10525         {
10526                 $output = '';
10527                 while (($start = strpos($data, '<!--')) !== false)
10528                 {
10529                         $output .= substr($data, 0, $start);
10530                         if (($end = strpos($data, '-->', $start)) !== false)
10531                         {
10532                                 $data = substr_replace($data, '', 0, $end + 3);
10533                         }
10534                         else
10535                         {
10536                                 $data = '';
10537                         }
10538                 }
10539                 return $output . $data;
10540         }
10541
10542         function parse_date($dt)
10543         {
10544                 $parser = SimplePie_Parse_Date::get();
10545                 return $parser->parse($dt);
10546         }
10547
10548         /**
10549          * Decode HTML entities
10550          *
10551          * @static
10552          * @access public
10553          * @param string $data Input data
10554          * @return string Output data
10555          */
10556         function entities_decode($data)
10557         {
10558                 $decoder = new SimplePie_Decode_HTML_Entities($data);
10559                 return $decoder->parse();
10560         }
10561
10562         /**
10563          * Remove RFC822 comments
10564          *
10565          * @access public
10566          * @param string $data Data to strip comments from
10567          * @return string Comment stripped string
10568          */
10569         function uncomment_rfc822($string)
10570         {
10571                 $string = (string) $string;
10572                 $position = 0;
10573                 $length = strlen($string);
10574                 $depth = 0;
10575
10576                 $output = '';
10577
10578                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10579                 {
10580                         $output .= substr($string, $position, $pos - $position);
10581                         $position = $pos + 1;
10582                         if ($string[$pos - 1] !== '\\')
10583                         {
10584                                 $depth++;
10585                                 while ($depth && $position < $length)
10586                                 {
10587                                         $position += strcspn($string, '()', $position);
10588                                         if ($string[$position - 1] === '\\')
10589                                         {
10590                                                 $position++;
10591                                                 continue;
10592                                         }
10593                                         elseif (isset($string[$position]))
10594                                         {
10595                                                 switch ($string[$position])
10596                                                 {
10597                                                         case '(':
10598                                                                 $depth++;
10599                                                                 break;
10600
10601                                                         case ')':
10602                                                                 $depth--;
10603                                                                 break;
10604                                                 }
10605                                                 $position++;
10606                                         }
10607                                         else
10608                                         {
10609                                                 break;
10610                                         }
10611                                 }
10612                         }
10613                         else
10614                         {
10615                                 $output .= '(';
10616                         }
10617                 }
10618                 $output .= substr($string, $position);
10619
10620                 return $output;
10621         }
10622
10623         function parse_mime($mime)
10624         {
10625                 if (($pos = strpos($mime, ';')) === false)
10626                 {
10627                         return trim($mime);
10628                 }
10629                 else
10630                 {
10631                         return trim(substr($mime, 0, $pos));
10632                 }
10633         }
10634
10635         function htmlspecialchars_decode($string, $quote_style)
10636         {
10637                 if (function_exists('htmlspecialchars_decode'))
10638                 {
10639                         return htmlspecialchars_decode($string, $quote_style);
10640                 }
10641                 else
10642                 {
10643                         return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10644                 }
10645         }
10646
10647         function atom_03_construct_type($attribs)
10648         {
10649                 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10650                 {
10651                         $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10652                 }
10653                 else
10654                 {
10655                         $mode = SIMPLEPIE_CONSTRUCT_NONE;
10656                 }
10657                 if (isset($attribs['']['type']))
10658                 {
10659                         switch (strtolower(trim($attribs['']['type'])))
10660                         {
10661                                 case 'text':
10662                                 case 'text/plain':
10663                                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10664
10665                                 case 'html':
10666                                 case 'text/html':
10667                                         return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10668
10669                                 case 'xhtml':
10670                                 case 'application/xhtml+xml':
10671                                         return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10672
10673                                 default:
10674                                         return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10675                         }
10676                 }
10677                 else
10678                 {
10679                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10680                 }
10681         }
10682
10683         function atom_10_construct_type($attribs)
10684         {
10685                 if (isset($attribs['']['type']))
10686                 {
10687                         switch (strtolower(trim($attribs['']['type'])))
10688                         {
10689                                 case 'text':
10690                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10691
10692                                 case 'html':
10693                                         return SIMPLEPIE_CONSTRUCT_HTML;
10694
10695                                 case 'xhtml':
10696                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10697
10698                                 default:
10699                                         return SIMPLEPIE_CONSTRUCT_NONE;
10700                         }
10701                 }
10702                 return SIMPLEPIE_CONSTRUCT_TEXT;
10703         }
10704
10705         function atom_10_content_construct_type($attribs)
10706         {
10707                 if (isset($attribs['']['type']))
10708                 {
10709                         $type = strtolower(trim($attribs['']['type']));
10710                         switch ($type)
10711                         {
10712                                 case 'text':
10713                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10714
10715                                 case 'html':
10716                                         return SIMPLEPIE_CONSTRUCT_HTML;
10717
10718                                 case 'xhtml':
10719                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10720                         }
10721                         if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10722                         {
10723                                 return SIMPLEPIE_CONSTRUCT_NONE;
10724                         }
10725                         else
10726                         {
10727                                 return SIMPLEPIE_CONSTRUCT_BASE64;
10728                         }
10729                 }
10730                 else
10731                 {
10732                         return SIMPLEPIE_CONSTRUCT_TEXT;
10733                 }
10734         }
10735
10736         function is_isegment_nz_nc($string)
10737         {
10738                 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);
10739         }
10740
10741         function space_seperated_tokens($string)
10742         {
10743                 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10744                 $string_length = strlen($string);
10745
10746                 $position = strspn($string, $space_characters);
10747                 $tokens = array();
10748
10749                 while ($position < $string_length)
10750                 {
10751                         $len = strcspn($string, $space_characters, $position);
10752                         $tokens[] = substr($string, $position, $len);
10753                         $position += $len;
10754                         $position += strspn($string, $space_characters, $position);
10755                 }
10756
10757                 return $tokens;
10758         }
10759
10760         function array_unique($array)
10761         {
10762                 if (version_compare(PHP_VERSION, '5.2', '>='))
10763                 {
10764                         return array_unique($array);
10765                 }
10766                 else
10767                 {
10768                         $array = (array) $array;
10769                         $new_array = array();
10770                         $new_array_strings = array();
10771                         foreach ($array as $key => $value)
10772                         {
10773                                 if (is_object($value))
10774                                 {
10775                                         if (method_exists($value, '__toString'))
10776                                         {
10777                                                 $cmp = $value->__toString();
10778                                         }
10779                                         else
10780                                         {
10781                                                 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10782                                         }
10783                                 }
10784                                 elseif (is_array($value))
10785                                 {
10786                                         $cmp = (string) reset($value);
10787                                 }
10788                                 else
10789                                 {
10790                                         $cmp = (string) $value;
10791                                 }
10792                                 if (!in_array($cmp, $new_array_strings))
10793                                 {
10794                                         $new_array[$key] = $value;
10795                                         $new_array_strings[] = $cmp;
10796                                 }
10797                         }
10798                         return $new_array;
10799                 }
10800         }
10801
10802         /**
10803          * Converts a unicode codepoint to a UTF-8 character
10804          *
10805          * @static
10806          * @access public
10807          * @param int $codepoint Unicode codepoint
10808          * @return string UTF-8 character
10809          */
10810         function codepoint_to_utf8($codepoint)
10811         {
10812                 static $cache = array();
10813                 $codepoint = (int) $codepoint;
10814                 if (isset($cache[$codepoint]))
10815                 {
10816                         return $cache[$codepoint];
10817                 }
10818                 elseif ($codepoint < 0)
10819                 {
10820                         return $cache[$codepoint] = false;
10821                 }
10822                 else if ($codepoint <= 0x7f)
10823                 {
10824                         return $cache[$codepoint] = chr($codepoint);
10825                 }
10826                 else if ($codepoint <= 0x7ff)
10827                 {
10828                         return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10829                 }
10830                 else if ($codepoint <= 0xffff)
10831                 {
10832                         return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10833                 }
10834                 else if ($codepoint <= 0x10ffff)
10835                 {
10836                         return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10837                 }
10838                 else
10839                 {
10840                         // U+FFFD REPLACEMENT CHARACTER
10841                         return $cache[$codepoint] = "\xEF\xBF\xBD";
10842                 }
10843         }
10844
10845         /**
10846          * Re-implementation of PHP 5's stripos()
10847          *
10848          * Returns the numeric position of the first occurrence of needle in the
10849          * haystack string.
10850          *
10851          * @static
10852          * @access string
10853          * @param object $haystack
10854          * @param string $needle Note that the needle may be a string of one or more
10855          *     characters. If needle is not a string, it is converted to an integer
10856          *     and applied as the ordinal value of a character.
10857          * @param int $offset The optional offset parameter allows you to specify which
10858          *     character in haystack to start searching. The position returned is still
10859          *     relative to the beginning of haystack.
10860          * @return bool If needle is not found, stripos() will return boolean false.
10861          */
10862         function stripos($haystack, $needle, $offset = 0)
10863         {
10864                 if (function_exists('stripos'))
10865                 {
10866                         return stripos($haystack, $needle, $offset);
10867                 }
10868                 else
10869                 {
10870                         if (is_string($needle))
10871                         {
10872                                 $needle = strtolower($needle);
10873                         }
10874                         elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10875                         {
10876                                 $needle = strtolower(chr($needle));
10877                         }
10878                         else
10879                         {
10880                                 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10881                                 return false;
10882                         }
10883
10884                         return strpos(strtolower($haystack), $needle, $offset);
10885                 }
10886         }
10887
10888         /**
10889          * Similar to parse_str()
10890          *
10891          * Returns an associative array of name/value pairs, where the value is an
10892          * array of values that have used the same name
10893          *
10894          * @static
10895          * @access string
10896          * @param string $str The input string.
10897          * @return array
10898          */
10899         function parse_str($str)
10900         {
10901                 $return = array();
10902                 $str = explode('&', $str);
10903
10904                 foreach ($str as $section)
10905                 {
10906                         if (strpos($section, '=') !== false)
10907                         {
10908                                 list($name, $value) = explode('=', $section, 2);
10909                                 $return[urldecode($name)][] = urldecode($value);
10910                         }
10911                         else
10912                         {
10913                                 $return[urldecode($section)][] = null;
10914                         }
10915                 }
10916
10917                 return $return;
10918         }
10919
10920         /**
10921          * Detect XML encoding, as per XML 1.0 Appendix F.1
10922          *
10923          * @todo Add support for EBCDIC
10924          * @param string $data XML data
10925          * @return array Possible encodings
10926          */
10927         function xml_encoding($data)
10928         {
10929                 // UTF-32 Big Endian BOM
10930                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10931                 {
10932                         $encoding[] = 'UTF-32BE';
10933                 }
10934                 // UTF-32 Little Endian BOM
10935                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10936                 {
10937                         $encoding[] = 'UTF-32LE';
10938                 }
10939                 // UTF-16 Big Endian BOM
10940                 elseif (substr($data, 0, 2) === "\xFE\xFF")
10941                 {
10942                         $encoding[] = 'UTF-16BE';
10943                 }
10944                 // UTF-16 Little Endian BOM
10945                 elseif (substr($data, 0, 2) === "\xFF\xFE")
10946                 {
10947                         $encoding[] = 'UTF-16LE';
10948                 }
10949                 // UTF-8 BOM
10950                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10951                 {
10952                         $encoding[] = 'UTF-8';
10953                 }
10954                 // UTF-32 Big Endian Without BOM
10955                 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")
10956                 {
10957                         if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10958                         {
10959                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10960                                 if ($parser->parse())
10961                                 {
10962                                         $encoding[] = $parser->encoding;
10963                                 }
10964                         }
10965                         $encoding[] = 'UTF-32BE';
10966                 }
10967                 // UTF-32 Little Endian Without BOM
10968                 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")
10969                 {
10970                         if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10971                         {
10972                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10973                                 if ($parser->parse())
10974                                 {
10975                                         $encoding[] = $parser->encoding;
10976                                 }
10977                         }
10978                         $encoding[] = 'UTF-32LE';
10979                 }
10980                 // UTF-16 Big Endian Without BOM
10981                 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10982                 {
10983                         if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10984                         {
10985                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10986                                 if ($parser->parse())
10987                                 {
10988                                         $encoding[] = $parser->encoding;
10989                                 }
10990                         }
10991                         $encoding[] = 'UTF-16BE';
10992                 }
10993                 // UTF-16 Little Endian Without BOM
10994                 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10995                 {
10996                         if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10997                         {
10998                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10999                                 if ($parser->parse())
11000                                 {
11001                                         $encoding[] = $parser->encoding;
11002                                 }
11003                         }
11004                         $encoding[] = 'UTF-16LE';
11005                 }
11006                 // US-ASCII (or superset)
11007                 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11008                 {
11009                         if ($pos = strpos($data, "\x3F\x3E"))
11010                         {
11011                                 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11012                                 if ($parser->parse())
11013                                 {
11014                                         $encoding[] = $parser->encoding;
11015                                 }
11016                         }
11017                         $encoding[] = 'UTF-8';
11018                 }
11019                 // Fallback to UTF-8
11020                 else
11021                 {
11022                         $encoding[] = 'UTF-8';
11023                 }
11024                 return $encoding;
11025         }
11026 }
11027
11028 /**
11029  * Decode HTML Entities
11030  *
11031  * This implements HTML5 as of revision 967 (2007-06-28)
11032  *
11033  * @package SimplePie
11034  */
11035 class SimplePie_Decode_HTML_Entities
11036 {
11037         /**
11038          * Data to be parsed
11039          *
11040          * @access private
11041          * @var string
11042          */
11043         var $data = '';
11044
11045         /**
11046          * Currently consumed bytes
11047          *
11048          * @access private
11049          * @var string
11050          */
11051         var $consumed = '';
11052
11053         /**
11054          * Position of the current byte being parsed
11055          *
11056          * @access private
11057          * @var int
11058          */
11059         var $position = 0;
11060
11061         /**
11062          * Create an instance of the class with the input data
11063          *
11064          * @access public
11065          * @param string $data Input data
11066          */
11067         function SimplePie_Decode_HTML_Entities($data)
11068         {
11069                 $this->data = $data;
11070         }
11071
11072         /**
11073          * Parse the input data
11074          *
11075          * @access public
11076          * @return string Output data
11077          */
11078         function parse()
11079         {
11080                 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11081                 {
11082                         $this->consume();
11083                         $this->entity();
11084                         $this->consumed = '';
11085                 }
11086                 return $this->data;
11087         }
11088
11089         /**
11090          * Consume the next byte
11091          *
11092          * @access private
11093          * @return mixed The next byte, or false, if there is no more data
11094          */
11095         function consume()
11096         {
11097                 if (isset($this->data[$this->position]))
11098                 {
11099                         $this->consumed .= $this->data[$this->position];
11100                         return $this->data[$this->position++];
11101                 }
11102                 else
11103                 {
11104                         $this->consumed = false;
11105                         return false;
11106                 }
11107         }
11108
11109         /**
11110          * Consume a range of characters
11111          *
11112          * @access private
11113          * @param string $chars Characters to consume
11114          * @return mixed A series of characters that match the range, or false
11115          */
11116         function consume_range($chars)
11117         {
11118                 if ($len = strspn($this->data, $chars, $this->position))
11119                 {
11120                         $data = substr($this->data, $this->position, $len);
11121                         $this->consumed .= $data;
11122                         $this->position += $len;
11123                         return $data;
11124                 }
11125                 else
11126                 {
11127                         $this->consumed = false;
11128                         return false;
11129                 }
11130         }
11131
11132         /**
11133          * Unconsume one byte
11134          *
11135          * @access private
11136          */
11137         function unconsume()
11138         {
11139                 $this->consumed = substr($this->consumed, 0, -1);
11140                 $this->position--;
11141         }
11142
11143         /**
11144          * Decode an entity
11145          *
11146          * @access private
11147          */
11148         function entity()
11149         {
11150                 switch ($this->consume())
11151                 {
11152                         case "\x09":
11153                         case "\x0A":
11154                         case "\x0B":
11155                         case "\x0B":
11156                         case "\x0C":
11157                         case "\x20":
11158                         case "\x3C":
11159                         case "\x26":
11160                         case false:
11161                                 break;
11162
11163                         case "\x23":
11164                                 switch ($this->consume())
11165                                 {
11166                                         case "\x78":
11167                                         case "\x58":
11168                                                 $range = '0123456789ABCDEFabcdef';
11169                                                 $hex = true;
11170                                                 break;
11171
11172                                         default:
11173                                                 $range = '0123456789';
11174                                                 $hex = false;
11175                                                 $this->unconsume();
11176                                                 break;
11177                                 }
11178
11179                                 if ($codepoint = $this->consume_range($range))
11180                                 {
11181                                         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");
11182
11183                                         if ($hex)
11184                                         {
11185                                                 $codepoint = hexdec($codepoint);
11186                                         }
11187                                         else
11188                                         {
11189                                                 $codepoint = intval($codepoint);
11190                                         }
11191
11192                                         if (isset($windows_1252_specials[$codepoint]))
11193                                         {
11194                                                 $replacement = $windows_1252_specials[$codepoint];
11195                                         }
11196                                         else
11197                                         {
11198                                                 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11199                                         }
11200
11201                                         if ($this->consume() != ';')
11202                                         {
11203                                                 $this->unconsume();
11204                                         }
11205
11206                                         $consumed_length = strlen($this->consumed);
11207                                         $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11208                                         $this->position += strlen($replacement) - $consumed_length;
11209                                 }
11210                                 break;
11211
11212                         default:
11213                                 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");
11214
11215                                 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11216                                 {
11217                                         $consumed = substr($this->consumed, 1);
11218                                         if (isset($entities[$consumed]))
11219                                         {
11220                                                 $match = $consumed;
11221                                         }
11222                                 }
11223
11224                                 if ($match !== null)
11225                                 {
11226                                         $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11227                                         $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11228                                 }
11229                                 break;
11230                 }
11231         }
11232 }
11233
11234 /**
11235  * Date Parser
11236  *
11237  * @package SimplePie
11238  */
11239 class SimplePie_Parse_Date
11240 {
11241         /**
11242          * Input data
11243          *
11244          * @access protected
11245          * @var string
11246          */
11247         var $date;
11248
11249         /**
11250          * List of days, calendar day name => ordinal day number in the week
11251          *
11252          * @access protected
11253          * @var array
11254          */
11255         var $day = array(
11256                 // English
11257                 'mon' => 1,
11258                 'monday' => 1,
11259                 'tue' => 2,
11260                 'tuesday' => 2,
11261                 'wed' => 3,
11262                 'wednesday' => 3,
11263                 'thu' => 4,
11264                 'thursday' => 4,
11265                 'fri' => 5,
11266                 'friday' => 5,
11267                 'sat' => 6,
11268                 'saturday' => 6,
11269                 'sun' => 7,
11270                 'sunday' => 7,
11271                 // Dutch
11272                 'maandag' => 1,
11273                 'dinsdag' => 2,
11274                 'woensdag' => 3,
11275                 'donderdag' => 4,
11276                 'vrijdag' => 5,
11277                 'zaterdag' => 6,
11278                 'zondag' => 7,
11279                 // French
11280                 'lundi' => 1,
11281                 'mardi' => 2,
11282                 'mercredi' => 3,
11283                 'jeudi' => 4,
11284                 'vendredi' => 5,
11285                 'samedi' => 6,
11286                 'dimanche' => 7,
11287                 // German
11288                 'montag' => 1,
11289                 'dienstag' => 2,
11290                 'mittwoch' => 3,
11291                 'donnerstag' => 4,
11292                 'freitag' => 5,
11293                 'samstag' => 6,
11294                 'sonnabend' => 6,
11295                 'sonntag' => 7,
11296                 // Italian
11297                 'lunedì' => 1,
11298                 'martedì' => 2,
11299                 'mercoledì' => 3,
11300                 'giovedì' => 4,
11301                 'venerdì' => 5,
11302                 'sabato' => 6,
11303                 'domenica' => 7,
11304                 // Spanish
11305                 'lunes' => 1,
11306                 'martes' => 2,
11307                 'miércoles' => 3,
11308                 'jueves' => 4,
11309                 'viernes' => 5,
11310                 'sábado' => 6,
11311                 'domingo' => 7,
11312                 // Finnish
11313                 'maanantai' => 1,
11314                 'tiistai' => 2,
11315                 'keskiviikko' => 3,
11316                 'torstai' => 4,
11317                 'perjantai' => 5,
11318                 'lauantai' => 6,
11319                 'sunnuntai' => 7,
11320                 // Hungarian
11321                 'hétfő' => 1,
11322                 'kedd' => 2,
11323                 'szerda' => 3,
11324                 'csütörtok' => 4,
11325                 'péntek' => 5,
11326                 'szombat' => 6,
11327                 'vasárnap' => 7,
11328                 // Greek
11329                 'Δευ' => 1,
11330                 'Τρι' => 2,
11331                 'Τετ' => 3,
11332                 'Πεμ' => 4,
11333                 'Παρ' => 5,
11334                 'Σαβ' => 6,
11335                 'Κυρ' => 7,
11336         );
11337
11338         /**
11339          * List of months, calendar month name => calendar month number
11340          *
11341          * @access protected
11342          * @var array
11343          */
11344         var $month = array(
11345                 // English
11346                 'jan' => 1,
11347                 'january' => 1,
11348                 'feb' => 2,
11349                 'february' => 2,
11350                 'mar' => 3,
11351                 'march' => 3,
11352                 'apr' => 4,
11353                 'april' => 4,
11354                 'may' => 5,
11355                 // No long form of May
11356                 'jun' => 6,
11357                 'june' => 6,
11358                 'jul' => 7,
11359                 'july' => 7,
11360                 'aug' => 8,
11361                 'august' => 8,
11362                 'sep' => 9,
11363                 'september' => 8,
11364                 'oct' => 10,
11365                 'october' => 10,
11366                 'nov' => 11,
11367                 'november' => 11,
11368                 'dec' => 12,
11369                 'december' => 12,
11370                 // Dutch
11371                 'januari' => 1,
11372                 'februari' => 2,
11373                 'maart' => 3,
11374                 'april' => 4,
11375                 'mei' => 5,
11376                 'juni' => 6,
11377                 'juli' => 7,
11378                 'augustus' => 8,
11379                 'september' => 9,
11380                 'oktober' => 10,
11381                 'november' => 11,
11382                 'december' => 12,
11383                 // French
11384                 'janvier' => 1,
11385                 'février' => 2,
11386                 'mars' => 3,
11387                 'avril' => 4,
11388                 'mai' => 5,
11389                 'juin' => 6,
11390                 'juillet' => 7,
11391                 'août' => 8,
11392                 'septembre' => 9,
11393                 'octobre' => 10,
11394                 'novembre' => 11,
11395                 'décembre' => 12,
11396                 // German
11397                 'januar' => 1,
11398                 'februar' => 2,
11399                 'märz' => 3,
11400                 'april' => 4,
11401                 'mai' => 5,
11402                 'juni' => 6,
11403                 'juli' => 7,
11404                 'august' => 8,
11405                 'september' => 9,
11406                 'oktober' => 10,
11407                 'november' => 11,
11408                 'dezember' => 12,
11409                 // Italian
11410                 'gennaio' => 1,
11411                 'febbraio' => 2,
11412                 'marzo' => 3,
11413                 'aprile' => 4,
11414                 'maggio' => 5,
11415                 'giugno' => 6,
11416                 'luglio' => 7,
11417                 'agosto' => 8,
11418                 'settembre' => 9,
11419                 'ottobre' => 10,
11420                 'novembre' => 11,
11421                 'dicembre' => 12,
11422                 // Spanish
11423                 'enero' => 1,
11424                 'febrero' => 2,
11425                 'marzo' => 3,
11426                 'abril' => 4,
11427                 'mayo' => 5,
11428                 'junio' => 6,
11429                 'julio' => 7,
11430                 'agosto' => 8,
11431                 'septiembre' => 9,
11432                 'setiembre' => 9,
11433                 'octubre' => 10,
11434                 'noviembre' => 11,
11435                 'diciembre' => 12,
11436                 // Finnish
11437                 'tammikuu' => 1,
11438                 'helmikuu' => 2,
11439                 'maaliskuu' => 3,
11440                 'huhtikuu' => 4,
11441                 'toukokuu' => 5,
11442                 'kesäkuu' => 6,
11443                 'heinäkuu' => 7,
11444                 'elokuu' => 8,
11445                 'suuskuu' => 9,
11446                 'lokakuu' => 10,
11447                 'marras' => 11,
11448                 'joulukuu' => 12,
11449                 // Hungarian
11450                 'január' => 1,
11451                 'február' => 2,
11452                 'március' => 3,
11453                 'április' => 4,
11454                 'május' => 5,
11455                 'június' => 6,
11456                 'július' => 7,
11457                 'augusztus' => 8,
11458                 'szeptember' => 9,
11459                 'október' => 10,
11460                 'november' => 11,
11461                 'december' => 12,
11462                 // Greek
11463                 'Ιαν' => 1,
11464                 'Φεβ' => 2,
11465                 'Μάώ' => 3,
11466                 'Μαώ' => 3,
11467                 'Απρ' => 4,
11468                 'Μάι' => 5,
11469                 'Μαϊ' => 5,
11470                 'Μαι' => 5,
11471                 'Ιούν' => 6,
11472                 'Ιον' => 6,
11473                 'Ιούλ' => 7,
11474                 'Ιολ' => 7,
11475                 'Αύγ' => 8,
11476                 'Αυγ' => 8,
11477                 'Σεπ' => 9,
11478                 'Οκτ' => 10,
11479                 'Νοέ' => 11,
11480                 'Δεκ' => 12,
11481         );
11482
11483         /**
11484          * List of timezones, abbreviation => offset from UTC
11485          *
11486          * @access protected
11487          * @var array
11488          */
11489         var $timezone = array(
11490                 'ACDT' => 37800,
11491                 'ACIT' => 28800,
11492                 'ACST' => 34200,
11493                 'ACT' => -18000,
11494                 'ACWDT' => 35100,
11495                 'ACWST' => 31500,
11496                 'AEDT' => 39600,
11497                 'AEST' => 36000,
11498                 'AFT' => 16200,
11499                 'AKDT' => -28800,
11500                 'AKST' => -32400,
11501                 'AMDT' => 18000,
11502                 'AMT' => -14400,
11503                 'ANAST' => 46800,
11504                 'ANAT' => 43200,
11505                 'ART' => -10800,
11506                 'AZOST' => -3600,
11507                 'AZST' => 18000,
11508                 'AZT' => 14400,
11509                 'BIOT' => 21600,
11510                 'BIT' => -43200,
11511                 'BOT' => -14400,
11512                 'BRST' => -7200,
11513                 'BRT' => -10800,
11514                 'BST' => 3600,
11515                 'BTT' => 21600,
11516                 'CAST' => 18000,
11517                 'CAT' => 7200,
11518                 'CCT' => 23400,
11519                 'CDT' => -18000,
11520                 'CEDT' => 7200,
11521                 'CET' => 3600,
11522                 'CGST' => -7200,
11523                 'CGT' => -10800,
11524                 'CHADT' => 49500,
11525                 'CHAST' => 45900,
11526                 'CIST' => -28800,
11527                 'CKT' => -36000,
11528                 'CLDT' => -10800,
11529                 'CLST' => -14400,
11530                 'COT' => -18000,
11531                 'CST' => -21600,
11532                 'CVT' => -3600,
11533                 'CXT' => 25200,
11534                 'DAVT' => 25200,
11535                 'DTAT' => 36000,
11536                 'EADT' => -18000,
11537                 'EAST' => -21600,
11538                 'EAT' => 10800,
11539                 'ECT' => -18000,
11540                 'EDT' => -14400,
11541                 'EEST' => 10800,
11542                 'EET' => 7200,
11543                 'EGT' => -3600,
11544                 'EKST' => 21600,
11545                 'EST' => -18000,
11546                 'FJT' => 43200,
11547                 'FKDT' => -10800,
11548                 'FKST' => -14400,
11549                 'FNT' => -7200,
11550                 'GALT' => -21600,
11551                 'GEDT' => 14400,
11552                 'GEST' => 10800,
11553                 'GFT' => -10800,
11554                 'GILT' => 43200,
11555                 'GIT' => -32400,
11556                 'GST' => 14400,
11557                 'GST' => -7200,
11558                 'GYT' => -14400,
11559                 'HAA' => -10800,
11560                 'HAC' => -18000,
11561                 'HADT' => -32400,
11562                 'HAE' => -14400,
11563                 'HAP' => -25200,
11564                 'HAR' => -21600,
11565                 'HAST' => -36000,
11566                 'HAT' => -9000,
11567                 'HAY' => -28800,
11568                 'HKST' => 28800,
11569                 'HMT' => 18000,
11570                 'HNA' => -14400,
11571                 'HNC' => -21600,
11572                 'HNE' => -18000,
11573                 'HNP' => -28800,
11574                 'HNR' => -25200,
11575                 'HNT' => -12600,
11576                 'HNY' => -32400,
11577                 'IRDT' => 16200,
11578                 'IRKST' => 32400,
11579                 'IRKT' => 28800,
11580                 'IRST' => 12600,
11581                 'JFDT' => -10800,
11582                 'JFST' => -14400,
11583                 'JST' => 32400,
11584                 'KGST' => 21600,
11585                 'KGT' => 18000,
11586                 'KOST' => 39600,
11587                 'KOVST' => 28800,
11588                 'KOVT' => 25200,
11589                 'KRAST' => 28800,
11590                 'KRAT' => 25200,
11591                 'KST' => 32400,
11592                 'LHDT' => 39600,
11593                 'LHST' => 37800,
11594                 'LINT' => 50400,
11595                 'LKT' => 21600,
11596                 'MAGST' => 43200,
11597                 'MAGT' => 39600,
11598                 'MAWT' => 21600,
11599                 'MDT' => -21600,
11600                 'MESZ' => 7200,
11601                 'MEZ' => 3600,
11602                 'MHT' => 43200,
11603                 'MIT' => -34200,
11604                 'MNST' => 32400,
11605                 'MSDT' => 14400,
11606                 'MSST' => 10800,
11607                 'MST' => -25200,
11608                 'MUT' => 14400,
11609                 'MVT' => 18000,
11610                 'MYT' => 28800,
11611                 'NCT' => 39600,
11612                 'NDT' => -9000,
11613                 'NFT' => 41400,
11614                 'NMIT' => 36000,
11615                 'NOVST' => 25200,
11616                 'NOVT' => 21600,
11617                 'NPT' => 20700,
11618                 'NRT' => 43200,
11619                 'NST' => -12600,
11620                 'NUT' => -39600,
11621                 'NZDT' => 46800,
11622                 'NZST' => 43200,
11623                 'OMSST' => 25200,
11624                 'OMST' => 21600,
11625                 'PDT' => -25200,
11626                 'PET' => -18000,
11627                 'PETST' => 46800,
11628                 'PETT' => 43200,
11629                 'PGT' => 36000,
11630                 'PHOT' => 46800,
11631                 'PHT' => 28800,
11632                 'PKT' => 18000,
11633                 'PMDT' => -7200,
11634                 'PMST' => -10800,
11635                 'PONT' => 39600,
11636                 'PST' => -28800,
11637                 'PWT' => 32400,
11638                 'PYST' => -10800,
11639                 'PYT' => -14400,
11640                 'RET' => 14400,
11641                 'ROTT' => -10800,
11642                 'SAMST' => 18000,
11643                 'SAMT' => 14400,
11644                 'SAST' => 7200,
11645                 'SBT' => 39600,
11646                 'SCDT' => 46800,
11647                 'SCST' => 43200,
11648                 'SCT' => 14400,
11649                 'SEST' => 3600,
11650                 'SGT' => 28800,
11651                 'SIT' => 28800,
11652                 'SRT' => -10800,
11653                 'SST' => -39600,
11654                 'SYST' => 10800,
11655                 'SYT' => 7200,
11656                 'TFT' => 18000,
11657                 'THAT' => -36000,
11658                 'TJT' => 18000,
11659                 'TKT' => -36000,
11660                 'TMT' => 18000,
11661                 'TOT' => 46800,
11662                 'TPT' => 32400,
11663                 'TRUT' => 36000,
11664                 'TVT' => 43200,
11665                 'TWT' => 28800,
11666                 'UYST' => -7200,
11667                 'UYT' => -10800,
11668                 'UZT' => 18000,
11669                 'VET' => -14400,
11670                 'VLAST' => 39600,
11671                 'VLAT' => 36000,
11672                 'VOST' => 21600,
11673                 'VUT' => 39600,
11674                 'WAST' => 7200,
11675                 'WAT' => 3600,
11676                 'WDT' => 32400,
11677                 'WEST' => 3600,
11678                 'WFT' => 43200,
11679                 'WIB' => 25200,
11680                 'WIT' => 32400,
11681                 'WITA' => 28800,
11682                 'WKST' => 18000,
11683                 'WST' => 28800,
11684                 'YAKST' => 36000,
11685                 'YAKT' => 32400,
11686                 'YAPT' => 36000,
11687                 'YEKST' => 21600,
11688                 'YEKT' => 18000,
11689         );
11690
11691         /**
11692          * Cached PCRE for SimplePie_Parse_Date::$day
11693          *
11694          * @access protected
11695          * @var string
11696          */
11697         var $day_pcre;
11698
11699         /**
11700          * Cached PCRE for SimplePie_Parse_Date::$month
11701          *
11702          * @access protected
11703          * @var string
11704          */
11705         var $month_pcre;
11706
11707         /**
11708          * Array of user-added callback methods
11709          *
11710          * @access private
11711          * @var array
11712          */
11713         var $built_in = array();
11714
11715         /**
11716          * Array of user-added callback methods
11717          *
11718          * @access private
11719          * @var array
11720          */
11721         var $user = array();
11722
11723         /**
11724          * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11725          * self::month_pcre, and self::built_in
11726          *
11727          * @access private
11728          */
11729         function SimplePie_Parse_Date()
11730         {
11731                 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11732                 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11733
11734                 static $cache;
11735                 if (!isset($cache[get_class($this)]))
11736                 {
11737                         if (extension_loaded('Reflection'))
11738                         {
11739                                 $class = new ReflectionClass(get_class($this));
11740                                 $methods = $class->getMethods();
11741                                 $all_methods = array();
11742                                 foreach ($methods as $method)
11743                                 {
11744                                         $all_methods[] = $method->getName();
11745                                 }
11746                         }
11747                         else
11748                         {
11749                                 $all_methods = get_class_methods($this);
11750                         }
11751
11752                         foreach ($all_methods as $method)
11753                         {
11754                                 if (strtolower(substr($method, 0, 5)) === 'date_')
11755                                 {
11756                                         $cache[get_class($this)][] = $method;
11757                                 }
11758                         }
11759                 }
11760
11761                 foreach ($cache[get_class($this)] as $method)
11762                 {
11763                         $this->built_in[] = $method;
11764                 }
11765         }
11766
11767         /**
11768          * Get the object
11769          *
11770          * @access public
11771          */
11772         function get()
11773         {
11774                 static $object;
11775                 if (!$object)
11776                 {
11777                         $object = new SimplePie_Parse_Date;
11778                 }
11779                 return $object;
11780         }
11781
11782         /**
11783          * Parse a date
11784          *
11785          * @final
11786          * @access public
11787          * @param string $date Date to parse
11788          * @return int Timestamp corresponding to date string, or false on failure
11789          */
11790         function parse($date)
11791         {
11792                 foreach ($this->user as $method)
11793                 {
11794                         if (($returned = call_user_func($method, $date)) !== false)
11795                         {
11796                                 return $returned;
11797                         }
11798                 }
11799
11800                 foreach ($this->built_in as $method)
11801                 {
11802                         if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11803                         {
11804                                 return $returned;
11805                         }
11806                 }
11807
11808                 return false;
11809         }
11810
11811         /**
11812          * Add a callback method to parse a date
11813          *
11814          * @final
11815          * @access public
11816          * @param callback $callback
11817          */
11818         function add_callback($callback)
11819         {
11820                 if (is_callable($callback))
11821                 {
11822                         $this->user[] = $callback;
11823                 }
11824                 else
11825                 {
11826                         trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11827                 }
11828         }
11829
11830         /**
11831          * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11832          * well as allowing any of upper or lower case "T", horizontal tabs, or
11833          * spaces to be used as the time seperator (including more than one))
11834          *
11835          * @access protected
11836          * @return int Timestamp
11837          */
11838         function date_w3cdtf($date)
11839         {
11840                 static $pcre;
11841                 if (!$pcre)
11842                 {
11843                         $year = '([0-9]{4})';
11844                         $month = $day = $hour = $minute = $second = '([0-9]{2})';
11845                         $decimal = '([0-9]*)';
11846                         $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11847                         $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11848                 }
11849                 if (preg_match($pcre, $date, $match))
11850                 {
11851                         /*
11852                         Capturing subpatterns:
11853                         1: Year
11854                         2: Month
11855                         3: Day
11856                         4: Hour
11857                         5: Minute
11858                         6: Second
11859                         7: Decimal fraction of a second
11860                         8: Zulu
11861                         9: Timezone ±
11862                         10: Timezone hours
11863                         11: Timezone minutes
11864                         */
11865
11866                         // Fill in empty matches
11867                         for ($i = count($match); $i <= 3; $i++)
11868                         {
11869                                 $match[$i] = '1';
11870                         }
11871
11872                         for ($i = count($match); $i <= 7; $i++)
11873                         {
11874                                 $match[$i] = '0';
11875                         }
11876
11877                         // Numeric timezone
11878                         if (isset($match[9]) && $match[9] !== '')
11879                         {
11880                                 $timezone = $match[10] * 3600;
11881                                 $timezone += $match[11] * 60;
11882                                 if ($match[9] === '-')
11883                                 {
11884                                         $timezone = 0 - $timezone;
11885                                 }
11886                         }
11887                         else
11888                         {
11889                                 $timezone = 0;
11890                         }
11891
11892                         // Convert the number of seconds to an integer, taking decimals into account
11893                         $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11894
11895                         return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11896                 }
11897                 else
11898                 {
11899                         return false;
11900                 }
11901         }
11902
11903         /**
11904          * Remove RFC822 comments
11905          *
11906          * @access protected
11907          * @param string $data Data to strip comments from
11908          * @return string Comment stripped string
11909          */
11910         function remove_rfc2822_comments($string)
11911         {
11912                 $string = (string) $string;
11913                 $position = 0;
11914                 $length = strlen($string);
11915                 $depth = 0;
11916
11917                 $output = '';
11918
11919                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11920                 {
11921                         $output .= substr($string, $position, $pos - $position);
11922                         $position = $pos + 1;
11923                         if ($string[$pos - 1] !== '\\')
11924                         {
11925                                 $depth++;
11926                                 while ($depth && $position < $length)
11927                                 {
11928                                         $position += strcspn($string, '()', $position);
11929                                         if ($string[$position - 1] === '\\')
11930                                         {
11931                                                 $position++;
11932                                                 continue;
11933                                         }
11934                                         elseif (isset($string[$position]))
11935                                         {
11936                                                 switch ($string[$position])
11937                                                 {
11938                                                         case '(':
11939                                                                 $depth++;
11940                                                                 break;
11941
11942                                                         case ')':
11943                                                                 $depth--;
11944                                                                 break;
11945                                                 }
11946                                                 $position++;
11947                                         }
11948                                         else
11949                                         {
11950                                                 break;
11951                                         }
11952                                 }
11953                         }
11954                         else
11955                         {
11956                                 $output .= '(';
11957                         }
11958                 }
11959                 $output .= substr($string, $position);
11960
11961                 return $output;
11962         }
11963
11964         /**
11965          * Parse RFC2822's date format
11966          *
11967          * @access protected
11968          * @return int Timestamp
11969          */
11970         function date_rfc2822($date)
11971         {
11972                 static $pcre;
11973                 if (!$pcre)
11974                 {
11975                         $wsp = '[\x09\x20]';
11976                         $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11977                         $optional_fws = $fws . '?';
11978                         $day_name = $this->day_pcre;
11979                         $month = $this->month_pcre;
11980                         $day = '([0-9]{1,2})';
11981                         $hour = $minute = $second = '([0-9]{2})';
11982                         $year = '([0-9]{2,4})';
11983                         $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11984                         $character_zone = '([A-Z]{1,5})';
11985                         $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11986                         $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';
11987                 }
11988                 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11989                 {
11990                         /*
11991                         Capturing subpatterns:
11992                         1: Day name
11993                         2: Day
11994                         3: Month
11995                         4: Year
11996                         5: Hour
11997                         6: Minute
11998                         7: Second
11999                         8: Timezone ±
12000                         9: Timezone hours
12001                         10: Timezone minutes
12002                         11: Alphabetic timezone
12003                         */
12004
12005                         // Find the month number
12006                         $month = $this->month[strtolower($match[3])];
12007
12008                         // Numeric timezone
12009                         if ($match[8] !== '')
12010                         {
12011                                 $timezone = $match[9] * 3600;
12012                                 $timezone += $match[10] * 60;
12013                                 if ($match[8] === '-')
12014                                 {
12015                                         $timezone = 0 - $timezone;
12016                                 }
12017                         }
12018                         // Character timezone
12019                         elseif (isset($this->timezone[strtoupper($match[11])]))
12020                         {
12021                                 $timezone = $this->timezone[strtoupper($match[11])];
12022                         }
12023                         // Assume everything else to be -0000
12024                         else
12025                         {
12026                                 $timezone = 0;
12027                         }
12028
12029                         // Deal with 2/3 digit years
12030                         if ($match[4] < 50)
12031                         {
12032                                 $match[4] += 2000;
12033                         }
12034                         elseif ($match[4] < 1000)
12035                         {
12036                                 $match[4] += 1900;
12037                         }
12038
12039                         // Second is optional, if it is empty set it to zero
12040                         if ($match[7] !== '')
12041                         {
12042                                 $second = $match[7];
12043                         }
12044                         else
12045                         {
12046                                 $second = 0;
12047                         }
12048
12049                         return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12050                 }
12051                 else
12052                 {
12053                         return false;
12054                 }
12055         }
12056
12057         /**
12058          * Parse RFC850's date format
12059          *
12060          * @access protected
12061          * @return int Timestamp
12062          */
12063         function date_rfc850($date)
12064         {
12065                 static $pcre;
12066                 if (!$pcre)
12067                 {
12068                         $space = '[\x09\x20]+';
12069                         $day_name = $this->day_pcre;
12070                         $month = $this->month_pcre;
12071                         $day = '([0-9]{1,2})';
12072                         $year = $hour = $minute = $second = '([0-9]{2})';
12073                         $zone = '([A-Z]{1,5})';
12074                         $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12075                 }
12076                 if (preg_match($pcre, $date, $match))
12077                 {
12078                         /*
12079                         Capturing subpatterns:
12080                         1: Day name
12081                         2: Day
12082                         3: Month
12083                         4: Year
12084                         5: Hour
12085                         6: Minute
12086                         7: Second
12087                         8: Timezone
12088                         */
12089
12090                         // Month
12091                         $month = $this->month[strtolower($match[3])];
12092
12093                         // Character timezone
12094                         if (isset($this->timezone[strtoupper($match[8])]))
12095                         {
12096                                 $timezone = $this->timezone[strtoupper($match[8])];
12097                         }
12098                         // Assume everything else to be -0000
12099                         else
12100                         {
12101                                 $timezone = 0;
12102                         }
12103
12104                         // Deal with 2 digit year
12105                         if ($match[4] < 50)
12106                         {
12107                                 $match[4] += 2000;
12108                         }
12109                         else
12110                         {
12111                                 $match[4] += 1900;
12112                         }
12113
12114                         return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12115                 }
12116                 else
12117                 {
12118                         return false;
12119                 }
12120         }
12121
12122         /**
12123          * Parse C99's asctime()'s date format
12124          *
12125          * @access protected
12126          * @return int Timestamp
12127          */
12128         function date_asctime($date)
12129         {
12130                 static $pcre;
12131                 if (!$pcre)
12132                 {
12133                         $space = '[\x09\x20]+';
12134                         $wday_name = $this->day_pcre;
12135                         $mon_name = $this->month_pcre;
12136                         $day = '([0-9]{1,2})';
12137                         $hour = $sec = $min = '([0-9]{2})';
12138                         $year = '([0-9]{4})';
12139                         $terminator = '\x0A?\x00?';
12140                         $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12141                 }
12142                 if (preg_match($pcre, $date, $match))
12143                 {
12144                         /*
12145                         Capturing subpatterns:
12146                         1: Day name
12147                         2: Month
12148                         3: Day
12149                         4: Hour
12150                         5: Minute
12151                         6: Second
12152                         7: Year
12153                         */
12154
12155                         $month = $this->month[strtolower($match[2])];
12156                         return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12157                 }
12158                 else
12159                 {
12160                         return false;
12161                 }
12162         }
12163
12164         /**
12165          * Parse dates using strtotime()
12166          *
12167          * @access protected
12168          * @return int Timestamp
12169          */
12170         function date_strtotime($date)
12171         {
12172                 $strtotime = strtotime($date);
12173                 if ($strtotime === -1 || $strtotime === false)
12174                 {
12175                         return false;
12176                 }
12177                 else
12178                 {
12179                         return $strtotime;
12180                 }
12181         }
12182 }
12183
12184 /**
12185  * Content-type sniffing
12186  *
12187  * @package SimplePie
12188  */
12189 class SimplePie_Content_Type_Sniffer
12190 {
12191         /**
12192          * File object
12193          *
12194          * @var SimplePie_File
12195          * @access private
12196          */
12197         var $file;
12198
12199         /**
12200          * Create an instance of the class with the input file
12201          *
12202          * @access public
12203          * @param SimplePie_Content_Type_Sniffer $file Input file
12204          */
12205         function SimplePie_Content_Type_Sniffer($file)
12206         {
12207                 $this->file = $file;
12208         }
12209
12210         /**
12211          * Get the Content-Type of the specified file
12212          *
12213          * @access public
12214          * @return string Actual Content-Type
12215          */
12216         function get_type()
12217         {
12218                 if (isset($this->file->headers['content-type']))
12219                 {
12220                         if (!isset($this->file->headers['content-encoding'])
12221                                 && ($this->file->headers['content-type'] === 'text/plain'
12222                                         || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12223                                         || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12224                         {
12225                                 return $this->text_or_binary();
12226                         }
12227
12228                         if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12229                         {
12230                                 $official = substr($this->file->headers['content-type'], 0, $pos);
12231                         }
12232                         else
12233                         {
12234                                 $official = $this->file->headers['content-type'];
12235                         }
12236                         $official = strtolower($official);
12237
12238                         if ($official === 'unknown/unknown'
12239                                 || $official === 'application/unknown')
12240                         {
12241                                 return $this->unknown();
12242                         }
12243                         elseif (substr($official, -4) === '+xml'
12244                                 || $official === 'text/xml'
12245                                 || $official === 'application/xml')
12246                         {
12247                                 return $official;
12248                         }
12249                         elseif (substr($official, 0, 6) === 'image/')
12250                         {
12251                                 if ($return = $this->image())
12252                                 {
12253                                         return $return;
12254                                 }
12255                                 else
12256                                 {
12257                                         return $official;
12258                                 }
12259                         }
12260                         elseif ($official === 'text/html')
12261                         {
12262                                 return $this->feed_or_html();
12263                         }
12264                         else
12265                         {
12266                                 return $official;
12267                         }
12268                 }
12269                 else
12270                 {
12271                         return $this->unknown();
12272                 }
12273         }
12274
12275         /**
12276          * Sniff text or binary
12277          *
12278          * @access private
12279          * @return string Actual Content-Type
12280          */
12281         function text_or_binary()
12282         {
12283                 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12284                         || substr($this->file->body, 0, 2) === "\xFF\xFE"
12285                         || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12286                         || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12287                 {
12288                         return 'text/plain';
12289                 }
12290                 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12291                 {
12292                         return 'application/octect-stream';
12293                 }
12294                 else
12295                 {
12296                         return 'text/plain';
12297                 }
12298         }
12299
12300         /**
12301          * Sniff unknown
12302          *
12303          * @access private
12304          * @return string Actual Content-Type
12305          */
12306         function unknown()
12307         {
12308                 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12309                 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12310                         || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12311                         || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12312                 {
12313                         return 'text/html';
12314                 }
12315                 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12316                 {
12317                         return 'application/pdf';
12318                 }
12319                 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12320                 {
12321                         return 'application/postscript';
12322                 }
12323                 elseif (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 $this->text_or_binary();
12343                 }
12344         }
12345
12346         /**
12347          * Sniff images
12348          *
12349          * @access private
12350          * @return string Actual Content-Type
12351          */
12352         function image()
12353         {
12354                 if (substr($this->file->body, 0, 6) === 'GIF87a'
12355                         || substr($this->file->body, 0, 6) === 'GIF89a')
12356                 {
12357                         return 'image/gif';
12358                 }
12359                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12360                 {
12361                         return 'image/png';
12362                 }
12363                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12364                 {
12365                         return 'image/jpeg';
12366                 }
12367                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12368                 {
12369                         return 'image/bmp';
12370                 }
12371                 else
12372                 {
12373                         return false;
12374                 }
12375         }
12376
12377         /**
12378          * Sniff HTML
12379          *
12380          * @access private
12381          * @return string Actual Content-Type
12382          */
12383         function feed_or_html()
12384         {
12385                 $len = strlen($this->file->body);
12386                 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12387
12388                 while ($pos < $len)
12389                 {
12390                         switch ($this->file->body[$pos])
12391                         {
12392                                 case "\x09":
12393                                 case "\x0A":
12394                                 case "\x0D":
12395                                 case "\x20":
12396                                         $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12397                                         continue 2;
12398
12399                                 case '<':
12400                                         $pos++;
12401                                         break;
12402
12403                                 default:
12404                                         return 'text/html';
12405                         }
12406
12407                         if (substr($this->file->body, $pos, 3) === '!--')
12408                         {
12409                                 $pos += 3;
12410                                 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12411                                 {
12412                                         $pos += 3;
12413                                 }
12414                                 else
12415                                 {
12416                                         return 'text/html';
12417                                 }
12418                         }
12419                         elseif (substr($this->file->body, $pos, 1) === '!')
12420                         {
12421                                 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12422                                 {
12423                                         $pos++;
12424                                 }
12425                                 else
12426                                 {
12427                                         return 'text/html';
12428                                 }
12429                         }
12430                         elseif (substr($this->file->body, $pos, 1) === '?')
12431                         {
12432                                 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12433                                 {
12434                                         $pos += 2;
12435                                 }
12436                                 else
12437                                 {
12438                                         return 'text/html';
12439                                 }
12440                         }
12441                         elseif (substr($this->file->body, $pos, 3) === 'rss'
12442                                 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12443                         {
12444                                 return 'application/rss+xml';
12445                         }
12446                         elseif (substr($this->file->body, $pos, 4) === 'feed')
12447                         {
12448                                 return 'application/atom+xml';
12449                         }
12450                         else
12451                         {
12452                                 return 'text/html';
12453                         }
12454                 }
12455
12456                 return 'text/html';
12457         }
12458 }
12459
12460 /**
12461  * Parses the XML Declaration
12462  *
12463  * @package SimplePie
12464  */
12465 class SimplePie_XML_Declaration_Parser
12466 {
12467         /**
12468          * XML Version
12469          *
12470          * @access public
12471          * @var string
12472          */
12473         var $version = '1.0';
12474
12475         /**
12476          * Encoding
12477          *
12478          * @access public
12479          * @var string
12480          */
12481         var $encoding = 'UTF-8';
12482
12483         /**
12484          * Standalone
12485          *
12486          * @access public
12487          * @var bool
12488          */
12489         var $standalone = false;
12490
12491         /**
12492          * Current state of the state machine
12493          *
12494          * @access private
12495          * @var string
12496          */
12497         var $state = 'before_version_name';
12498
12499         /**
12500          * Input data
12501          *
12502          * @access private
12503          * @var string
12504          */
12505         var $data = '';
12506
12507         /**
12508          * Input data length (to avoid calling strlen() everytime this is needed)
12509          *
12510          * @access private
12511          * @var int
12512          */
12513         var $data_length = 0;
12514
12515         /**
12516          * Current position of the pointer
12517          *
12518          * @var int
12519          * @access private
12520          */
12521         var $position = 0;
12522
12523         /**
12524          * Create an instance of the class with the input data
12525          *
12526          * @access public
12527          * @param string $data Input data
12528          */
12529         function SimplePie_XML_Declaration_Parser($data)
12530         {
12531                 $this->data = $data;
12532                 $this->data_length = strlen($this->data);
12533         }
12534
12535         /**
12536          * Parse the input data
12537          *
12538          * @access public
12539          * @return bool true on success, false on failure
12540          */
12541         function parse()
12542         {
12543                 while ($this->state && $this->state !== 'emit' && $this->has_data())
12544                 {
12545                         $state = $this->state;
12546                         $this->$state();
12547                 }
12548                 $this->data = '';
12549                 if ($this->state === 'emit')
12550                 {
12551                         return true;
12552                 }
12553                 else
12554                 {
12555                         $this->version = '';
12556                         $this->encoding = '';
12557                         $this->standalone = '';
12558                         return false;
12559                 }
12560         }
12561
12562         /**
12563          * Check whether there is data beyond the pointer
12564          *
12565          * @access private
12566          * @return bool true if there is further data, false if not
12567          */
12568         function has_data()
12569         {
12570                 return (bool) ($this->position < $this->data_length);
12571         }
12572
12573         /**
12574          * Advance past any whitespace
12575          *
12576          * @return int Number of whitespace characters passed
12577          */
12578         function skip_whitespace()
12579         {
12580                 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12581                 $this->position += $whitespace;
12582                 return $whitespace;
12583         }
12584
12585         /**
12586          * Read value
12587          */
12588         function get_value()
12589         {
12590                 $quote = substr($this->data, $this->position, 1);
12591                 if ($quote === '"' || $quote === "'")
12592                 {
12593                         $this->position++;
12594                         $len = strcspn($this->data, $quote, $this->position);
12595                         if ($this->has_data())
12596                         {
12597                                 $value = substr($this->data, $this->position, $len);
12598                                 $this->position += $len + 1;
12599                                 return $value;
12600                         }
12601                 }
12602                 return false;
12603         }
12604
12605         function before_version_name()
12606         {
12607                 if ($this->skip_whitespace())
12608                 {
12609                         $this->state = 'version_name';
12610                 }
12611                 else
12612                 {
12613                         $this->state = false;
12614                 }
12615         }
12616
12617         function version_name()
12618         {
12619                 if (substr($this->data, $this->position, 7) === 'version')
12620                 {
12621                         $this->position += 7;
12622                         $this->skip_whitespace();
12623                         $this->state = 'version_equals';
12624                 }
12625                 else
12626                 {
12627                         $this->state = false;
12628                 }
12629         }
12630
12631         function version_equals()
12632         {
12633                 if (substr($this->data, $this->position, 1) === '=')
12634                 {
12635                         $this->position++;
12636                         $this->skip_whitespace();
12637                         $this->state = 'version_value';
12638                 }
12639                 else
12640                 {
12641                         $this->state = false;
12642                 }
12643         }
12644
12645         function version_value()
12646         {
12647                 if ($this->version = $this->get_value())
12648                 {
12649                         $this->skip_whitespace();
12650                         if ($this->has_data())
12651                         {
12652                                 $this->state = 'encoding_name';
12653                         }
12654                         else
12655                         {
12656                                 $this->state = 'emit';
12657                         }
12658                 }
12659                 else
12660                 {
12661                         $this->state = 'standalone_name';
12662                 }
12663         }
12664
12665         function encoding_name()
12666         {
12667                 if (substr($this->data, $this->position, 8) === 'encoding')
12668                 {
12669                         $this->position += 8;
12670                         $this->skip_whitespace();
12671                         $this->state = 'encoding_equals';
12672                 }
12673                 else
12674                 {
12675                         $this->state = false;
12676                 }
12677         }
12678
12679         function encoding_equals()
12680         {
12681                 if (substr($this->data, $this->position, 1) === '=')
12682                 {
12683                         $this->position++;
12684                         $this->skip_whitespace();
12685                         $this->state = 'encoding_value';
12686                 }
12687                 else
12688                 {
12689                         $this->state = false;
12690                 }
12691         }
12692
12693         function encoding_value()
12694         {
12695                 if ($this->encoding = $this->get_value())
12696                 {
12697                         $this->skip_whitespace();
12698                         if ($this->has_data())
12699                         {
12700                                 $this->state = 'standalone_name';
12701                         }
12702                         else
12703                         {
12704                                 $this->state = 'emit';
12705                         }
12706                 }
12707                 else
12708                 {
12709                         $this->state = false;
12710                 }
12711         }
12712
12713         function standalone_name()
12714         {
12715                 if (substr($this->data, $this->position, 10) === 'standalone')
12716                 {
12717                         $this->position += 10;
12718                         $this->skip_whitespace();
12719                         $this->state = 'standalone_equals';
12720                 }
12721                 else
12722                 {
12723                         $this->state = false;
12724                 }
12725         }
12726
12727         function standalone_equals()
12728         {
12729                 if (substr($this->data, $this->position, 1) === '=')
12730                 {
12731                         $this->position++;
12732                         $this->skip_whitespace();
12733                         $this->state = 'standalone_value';
12734                 }
12735                 else
12736                 {
12737                         $this->state = false;
12738                 }
12739         }
12740
12741         function standalone_value()
12742         {
12743                 if ($standalone = $this->get_value())
12744                 {
12745                         switch ($standalone)
12746                         {
12747                                 case 'yes':
12748                                         $this->standalone = true;
12749                                         break;
12750
12751                                 case 'no':
12752                                         $this->standalone = false;
12753                                         break;
12754
12755                                 default:
12756                                         $this->state = false;
12757                                         return;
12758                         }
12759
12760                         $this->skip_whitespace();
12761                         if ($this->has_data())
12762                         {
12763                                 $this->state = false;
12764                         }
12765                         else
12766                         {
12767                                 $this->state = 'emit';
12768                         }
12769                 }
12770                 else
12771                 {
12772                         $this->state = false;
12773                 }
12774         }
12775 }
12776
12777 class SimplePie_Locator
12778 {
12779         var $useragent;
12780         var $timeout;
12781         var $file;
12782         var $local = array();
12783         var $elsewhere = array();
12784         var $file_class = 'SimplePie_File';
12785         var $cached_entities = array();
12786         var $http_base;
12787         var $base;
12788         var $base_location = 0;
12789         var $checked_feeds = 0;
12790         var $max_checked_feeds = 10;
12791         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12792
12793         function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12794         {
12795                 $this->file =& $file;
12796                 $this->file_class = $file_class;
12797                 $this->useragent = $useragent;
12798                 $this->timeout = $timeout;
12799                 $this->max_checked_feeds = $max_checked_feeds;
12800                 $this->content_type_sniffer_class = $content_type_sniffer_class;
12801         }
12802
12803         function find($type = SIMPLEPIE_LOCATOR_ALL)
12804         {
12805                 if ($this->is_feed($this->file))
12806                 {
12807                         return $this->file;
12808                 }
12809
12810                 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12811                 {
12812                         $sniffer = new $this->content_type_sniffer_class($this->file);
12813                         if ($sniffer->get_type() !== 'text/html')
12814                         {
12815                                 return null;
12816                         }
12817                 }
12818
12819                 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12820                 {
12821                         $this->get_base();
12822                 }
12823
12824                 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12825                 {
12826                         return $working;
12827                 }
12828
12829                 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12830                 {
12831                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12832                         {
12833                                 return $working;
12834                         }
12835
12836                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12837                         {
12838                                 return $working;
12839                         }
12840
12841                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12842                         {
12843                                 return $working;
12844                         }
12845
12846                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12847                         {
12848                                 return $working;
12849                         }
12850                 }
12851                 return null;
12852         }
12853
12854         function is_feed(&$file)
12855         {
12856                 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12857                 {
12858                         $sniffer = new $this->content_type_sniffer_class($file);
12859                         $sniffed = $sniffer->get_type();
12860                         if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12861                         {
12862                                 return true;
12863                         }
12864                         else
12865                         {
12866                                 return false;
12867                         }
12868                 }
12869                 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12870                 {
12871                         return true;
12872                 }
12873                 else
12874                 {
12875                         return false;
12876                 }
12877         }
12878
12879         function get_base()
12880         {
12881                 $this->http_base = $this->file->url;
12882                 $this->base = $this->http_base;
12883                 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12884                 foreach ($elements as $element)
12885                 {
12886                         if ($element['attribs']['href']['data'] !== '')
12887                         {
12888                                 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12889                                 $this->base_location = $element['offset'];
12890                                 break;
12891                         }
12892                 }
12893         }
12894
12895         function autodiscovery()
12896         {
12897                 $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));
12898                 $done = array();
12899                 foreach ($links as $link)
12900                 {
12901                         if ($this->checked_feeds == $this->max_checked_feeds)
12902                         {
12903                                 break;
12904                         }
12905                         if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12906                         {
12907                                 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12908
12909                                 if ($this->base_location < $link['offset'])
12910                                 {
12911                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12912                                 }
12913                                 else
12914                                 {
12915                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12916                                 }
12917
12918                                 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'))))
12919                                 {
12920                                         $this->checked_feeds++;
12921                                         $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12922                                         if ($this->is_feed($feed))
12923                                         {
12924                                                 return $feed;
12925                                         }
12926                                 }
12927                                 $done[] = $href;
12928                         }
12929                 }
12930                 return null;
12931         }
12932
12933         function get_links()
12934         {
12935                 $links = SimplePie_Misc::get_element('a', $this->file->body);
12936                 foreach ($links as $link)
12937                 {
12938                         if (isset($link['attribs']['href']['data']))
12939                         {
12940                                 $href = trim($link['attribs']['href']['data']);
12941                                 $parsed = SimplePie_Misc::parse_url($href);
12942                                 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12943                                 {
12944                                         if ($this->base_location < $link['offset'])
12945                                         {
12946                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12947                                         }
12948                                         else
12949                                         {
12950                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12951                                         }
12952
12953                                         $current = SimplePie_Misc::parse_url($this->file->url);
12954
12955                                         if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12956                                         {
12957                                                 $this->local[] = $href;
12958                                         }
12959                                         else
12960                                         {
12961                                                 $this->elsewhere[] = $href;
12962                                         }
12963                                 }
12964                         }
12965                 }
12966                 $this->local = array_unique($this->local);
12967                 $this->elsewhere = array_unique($this->elsewhere);
12968                 if (!empty($this->local) || !empty($this->elsewhere))
12969                 {
12970                         return true;
12971                 }
12972                 return null;
12973         }
12974
12975         function extension(&$array)
12976         {
12977                 foreach ($array as $key => $value)
12978                 {
12979                         if ($this->checked_feeds == $this->max_checked_feeds)
12980                         {
12981                                 break;
12982                         }
12983                         if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12984                         {
12985                                 $this->checked_feeds++;
12986                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12987                                 if ($this->is_feed($feed))
12988                                 {
12989                                         return $feed;
12990                                 }
12991                                 else
12992                                 {
12993                                         unset($array[$key]);
12994                                 }
12995                         }
12996                 }
12997                 return null;
12998         }
12999
13000         function body(&$array)
13001         {
13002                 foreach ($array as $key => $value)
13003                 {
13004                         if ($this->checked_feeds == $this->max_checked_feeds)
13005                         {
13006                                 break;
13007                         }
13008                         if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13009                         {
13010                                 $this->checked_feeds++;
13011                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
13012                                 if ($this->is_feed($feed))
13013                                 {
13014                                         return $feed;
13015                                 }
13016                                 else
13017                                 {
13018                                         unset($array[$key]);
13019                                 }
13020                         }
13021                 }
13022                 return null;
13023         }
13024 }
13025
13026 class SimplePie_Parser
13027 {
13028         var $error_code;
13029         var $error_string;
13030         var $current_line;
13031         var $current_column;
13032         var $current_byte;
13033         var $separator = ' ';
13034         var $feed = false;
13035         var $namespace = array('');
13036         var $element = array('');
13037         var $xml_base = array('');
13038         var $xml_base_explicit = array(false);
13039         var $xml_lang = array('');
13040         var $data = array();
13041         var $datas = array(array());
13042         var $current_xhtml_construct = -1;
13043         var $encoding;
13044
13045         function parse(&$data, $encoding)
13046         {
13047                 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13048                 if (strtoupper($encoding) == 'US-ASCII')
13049                 {
13050                         $this->encoding = 'UTF-8';
13051                 }
13052                 else
13053                 {
13054                         $this->encoding = $encoding;
13055                 }
13056
13057                 // Strip BOM:
13058                 // UTF-32 Big Endian BOM
13059                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13060                 {
13061                         $data = substr($data, 4);
13062                 }
13063                 // UTF-32 Little Endian BOM
13064                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13065                 {
13066                         $data = substr($data, 4);
13067                 }
13068                 // UTF-16 Big Endian BOM
13069                 elseif (substr($data, 0, 2) === "\xFE\xFF")
13070                 {
13071                         $data = substr($data, 2);
13072                 }
13073                 // UTF-16 Little Endian BOM
13074                 elseif (substr($data, 0, 2) === "\xFF\xFE")
13075                 {
13076                         $data = substr($data, 2);
13077                 }
13078                 // UTF-8 BOM
13079                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13080                 {
13081                         $data = substr($data, 3);
13082                 }
13083
13084                 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13085                 {
13086                         $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13087                         if ($declaration->parse())
13088                         {
13089                                 $data = substr($data, $pos + 2);
13090                                 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13091                         }
13092                         else
13093                         {
13094                                 $this->error_string = 'SimplePie bug! Please report this!';
13095                                 return false;
13096                         }
13097                 }
13098
13099                 // Work around libxml bug
13100                 $data = str_replace('&lt;', '&#60;', $data);
13101                 $data = str_replace('&gt;', '&#62;', $data);
13102                 $data = str_replace('&amp;', '&#38;', $data);
13103                 $data = str_replace('&apos;', '&#39;', $data);
13104                 $data = str_replace('&quot;', '&#34;', $data);
13105
13106                 $return = true;
13107
13108                 // Create the parser
13109                 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13110                 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13111                 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13112                 xml_set_object($xml, $this);
13113                 xml_set_character_data_handler($xml, 'cdata');
13114                 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13115
13116                 // Parse!
13117                 if (!xml_parse($xml, $data, true))
13118                 {
13119                         $this->error_code = xml_get_error_code($xml);
13120                         $this->error_string = xml_error_string($this->error_code);
13121                         $return = false;
13122                 }
13123                 $this->current_line = xml_get_current_line_number($xml);
13124                 $this->current_column = xml_get_current_column_number($xml);
13125                 $this->current_byte = xml_get_current_byte_index($xml);
13126                 xml_parser_free($xml);
13127                 return $return;
13128         }
13129
13130         function get_error_code()
13131         {
13132                 return $this->error_code;
13133         }
13134
13135         function get_error_string()
13136         {
13137                 return $this->error_string;
13138         }
13139
13140         function get_current_line()
13141         {
13142                 return $this->current_line;
13143         }
13144
13145         function get_current_column()
13146         {
13147                 return $this->current_column;
13148         }
13149
13150         function get_current_byte()
13151         {
13152                 return $this->current_byte;
13153         }
13154
13155         function get_data()
13156         {
13157                 return $this->data;
13158         }
13159
13160         function tag_open($parser, $tag, $attributes)
13161         {
13162                 if ($this->feed === 0)
13163                 {
13164                         return;
13165                 }
13166                 elseif ($this->feed == false)
13167                 {
13168                         if (in_array($tag, array(
13169                                 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13170                                 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13171                                 'rss',
13172                                 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13173                         )))
13174                         {
13175                                         $this->feed = 1;
13176                         }
13177                 }
13178                 else
13179                 {
13180                         $this->feed++;
13181                 }
13182
13183                 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13184
13185                 $attribs = array();
13186                 foreach ($attributes as $name => $value)
13187                 {
13188                         list($attrib_namespace, $attribute) = $this->split_ns($name);
13189                         $attribs[$attrib_namespace][$attribute] = $value;
13190                 }
13191
13192                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13193                 {
13194                         $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13195                         $this->xml_base_explicit[] = true;
13196                 }
13197                 else
13198                 {
13199                         $this->xml_base[] = end($this->xml_base);
13200                         $this->xml_base_explicit[] = end($this->xml_base_explicit);
13201                 }
13202
13203                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13204                 {
13205                         $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13206                 }
13207                 else
13208                 {
13209                         $this->xml_lang[] = end($this->xml_lang);
13210                 }
13211
13212                 if ($this->current_xhtml_construct >= 0)
13213                 {
13214                         $this->current_xhtml_construct++;
13215                         if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13216                         {
13217                                 $this->data['data'] .= '<' . end($this->element);
13218                                 if (isset($attribs['']))
13219                                 {
13220                                         foreach ($attribs[''] as $name => $value)
13221                                         {
13222                                                 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13223                                         }
13224                                 }
13225                                 $this->data['data'] .= '>';
13226                         }
13227                 }
13228                 else
13229                 {
13230                         $this->datas[] =& $this->data;
13231                         $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13232                         $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));
13233                         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')
13234                         || (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'))
13235                         {
13236                                 $this->current_xhtml_construct = 0;
13237                         }
13238                 }
13239         }
13240
13241         function cdata($parser, $cdata)
13242         {
13243                 if ($this->current_xhtml_construct >= 0)
13244                 {
13245                         $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13246                 }
13247                 elseif ($this->feed > 1)
13248                 {
13249                         $this->data['data'] .= $cdata;
13250                 }
13251         }
13252
13253         function tag_close($parser, $tag)
13254         {
13255                 if (!$this->feed)
13256                 {
13257                         return;
13258                 }
13259
13260                 if ($this->current_xhtml_construct >= 0)
13261                 {
13262                         $this->current_xhtml_construct--;
13263                         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')))
13264                         {
13265                                 $this->data['data'] .= '</' . end($this->element) . '>';
13266                         }
13267                 }
13268                 if ($this->current_xhtml_construct == -1)
13269                 {
13270                         $this->data =& $this->datas[$this->feed];
13271                         array_pop($this->datas);
13272                 }
13273
13274                 array_pop($this->element);
13275                 array_pop($this->namespace);
13276                 array_pop($this->xml_base);
13277                 array_pop($this->xml_base_explicit);
13278                 array_pop($this->xml_lang);
13279                 $this->feed--;
13280         }
13281
13282         function split_ns($string)
13283         {
13284                 static $cache = array();
13285                 if (!isset($cache[$string]))
13286                 {
13287                         if ($pos = strpos($string, $this->separator))
13288                         {
13289                                 static $separator_length;
13290                                 if (!$separator_length)
13291                                 {
13292                                         $separator_length = strlen($this->separator);
13293                                 }
13294                                 $namespace = substr($string, 0, $pos);
13295                                 $local_name = substr($string, $pos + $separator_length);
13296                                 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13297                                 {
13298                                         $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13299                                 }
13300
13301                                 // Normalize the Media RSS namespaces
13302                                 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13303                                 {
13304                                         $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13305                                 }
13306                                 $cache[$string] = array($namespace, $local_name);
13307                         }
13308                         else
13309                         {
13310                                 $cache[$string] = array('', $string);
13311                         }
13312                 }
13313                 return $cache[$string];
13314         }
13315 }
13316
13317 /**
13318  * @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
13319  */
13320 class SimplePie_Sanitize
13321 {
13322         // Private vars
13323         var $base;
13324
13325         // Options
13326         var $remove_div = true;
13327         var $image_handler = '';
13328         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13329         var $encode_instead_of_strip = false;
13330         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13331         var $strip_comments = false;
13332         var $output_encoding = 'UTF-8';
13333         var $enable_cache = true;
13334         var $cache_location = './cache';
13335         var $cache_name_function = 'md5';
13336         var $cache_class = 'SimplePie_Cache';
13337         var $file_class = 'SimplePie_File';
13338         var $timeout = 10;
13339         var $useragent = '';
13340         var $force_fsockopen = false;
13341
13342         var $replace_url_attributes = array(
13343                 'a' => 'href',
13344                 'area' => 'href',
13345                 'blockquote' => 'cite',
13346                 'del' => 'cite',
13347                 'form' => 'action',
13348                 'img' => array('longdesc', 'src'),
13349                 'input' => 'src',
13350                 'ins' => 'cite',
13351                 'q' => 'cite'
13352         );
13353
13354         function remove_div($enable = true)
13355         {
13356                 $this->remove_div = (bool) $enable;
13357         }
13358
13359         function set_image_handler($page = false)
13360         {
13361                 if ($page)
13362                 {
13363                         $this->image_handler = (string) $page;
13364                 }
13365                 else
13366                 {
13367                         $this->image_handler = false;
13368                 }
13369         }
13370
13371         function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13372         {
13373                 if (isset($enable_cache))
13374                 {
13375                         $this->enable_cache = (bool) $enable_cache;
13376                 }
13377
13378                 if ($cache_location)
13379                 {
13380                         $this->cache_location = (string) $cache_location;
13381                 }
13382
13383                 if ($cache_name_function)
13384                 {
13385                         $this->cache_name_function = (string) $cache_name_function;
13386                 }
13387
13388                 if ($cache_class)
13389                 {
13390                         $this->cache_class = (string) $cache_class;
13391                 }
13392         }
13393
13394         function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13395         {
13396                 if ($file_class)
13397                 {
13398                         $this->file_class = (string) $file_class;
13399                 }
13400
13401                 if ($timeout)
13402                 {
13403                         $this->timeout = (string) $timeout;
13404                 }
13405
13406                 if ($useragent)
13407                 {
13408                         $this->useragent = (string) $useragent;
13409                 }
13410
13411                 if ($force_fsockopen)
13412                 {
13413                         $this->force_fsockopen = (string) $force_fsockopen;
13414                 }
13415         }
13416
13417         function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13418         {
13419                 if ($tags)
13420                 {
13421                         if (is_array($tags))
13422                         {
13423                                 $this->strip_htmltags = $tags;
13424                         }
13425                         else
13426                         {
13427                                 $this->strip_htmltags = explode(',', $tags);
13428                         }
13429                 }
13430                 else
13431                 {
13432                         $this->strip_htmltags = false;
13433                 }
13434         }
13435
13436         function encode_instead_of_strip($encode = false)
13437         {
13438                 $this->encode_instead_of_strip = (bool) $encode;
13439         }
13440
13441         function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13442         {
13443                 if ($attribs)
13444                 {
13445                         if (is_array($attribs))
13446                         {
13447                                 $this->strip_attributes = $attribs;
13448                         }
13449                         else
13450                         {
13451                                 $this->strip_attributes = explode(',', $attribs);
13452                         }
13453                 }
13454                 else
13455                 {
13456                         $this->strip_attributes = false;
13457                 }
13458         }
13459
13460         function strip_comments($strip = false)
13461         {
13462                 $this->strip_comments = (bool) $strip;
13463         }
13464
13465         function set_output_encoding($encoding = 'UTF-8')
13466         {
13467                 $this->output_encoding = (string) $encoding;
13468         }
13469
13470         /**
13471          * Set element/attribute key/value pairs of HTML attributes
13472          * containing URLs that need to be resolved relative to the feed
13473          *
13474          * @access public
13475          * @since 1.0
13476          * @param array $element_attribute Element/attribute key/value pairs
13477          */
13478         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'))
13479         {
13480                 $this->replace_url_attributes = (array) $element_attribute;
13481         }
13482
13483         function sanitize($data, $type, $base = '')
13484         {
13485                 $data = trim($data);
13486                 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13487                 {
13488                         if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13489                         {
13490                                 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))
13491                                 {
13492                                         $type |= SIMPLEPIE_CONSTRUCT_HTML;
13493                                 }
13494                                 else
13495                                 {
13496                                         $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13497                                 }
13498                         }
13499
13500                         if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13501                         {
13502                                 $data = base64_decode($data);
13503                         }
13504
13505                         if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13506                         {
13507                                 if ($this->remove_div)
13508                                 {
13509                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13510                                         $data = preg_replace('/<\/div>$/', '', $data);
13511                                 }
13512                                 else
13513                                 {
13514                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13515                                 }
13516                         }
13517
13518                         if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13519                         {
13520                                 // Strip comments
13521                                 if ($this->strip_comments)
13522                                 {
13523                                         $data = SimplePie_Misc::strip_comments($data);
13524                                 }
13525
13526                                 // Strip out HTML tags and attributes that might cause various security problems.
13527                                 // Based on recommendations by Mark Pilgrim at:
13528                                 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13529                                 if ($this->strip_htmltags)
13530                                 {
13531                                         foreach ($this->strip_htmltags as $tag)
13532                                         {
13533                                                 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13534                                                 while (preg_match($pcre, $data))
13535                                                 {
13536                                                         $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13537                                                 }
13538                                         }
13539                                 }
13540
13541                                 if ($this->strip_attributes)
13542                                 {
13543                                         foreach ($this->strip_attributes as $attrib)
13544                                         {
13545                                                 $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);
13546                                         }
13547                                 }
13548
13549                                 // Replace relative URLs
13550                                 $this->base = $base;
13551                                 foreach ($this->replace_url_attributes as $element => $attributes)
13552                                 {
13553                                         $data = $this->replace_urls($data, $element, $attributes);
13554                                 }
13555
13556                                 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13557                                 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13558                                 {
13559                                         $images = SimplePie_Misc::get_element('img', $data);
13560                                         foreach ($images as $img)
13561                                         {
13562                                                 if (isset($img['attribs']['src']['data']))
13563                                                 {
13564                                                         $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13565                                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13566
13567                                                         if ($cache->load())
13568                                                         {
13569                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13570                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13571                                                         }
13572                                                         else
13573                                                         {
13574                                                                 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13575                                                                 $headers = $file->headers;
13576
13577                                                                 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13578                                                                 {
13579                                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13580                                                                         {
13581                                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13582                                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13583                                                                         }
13584                                                                         else
13585                                                                         {
13586                                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13587                                                                         }
13588                                                                 }
13589                                                         }
13590                                                 }
13591                                         }
13592                                 }
13593
13594                                 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13595                                 $data = trim($data);
13596                         }
13597
13598                         if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13599                         {
13600                                 $data = SimplePie_Misc::absolutize_url($data, $base);
13601                         }
13602
13603                         if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13604                         {
13605                                 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13606                         }
13607
13608                         if ($this->output_encoding != 'UTF-8')
13609                         {
13610                                 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13611                         }
13612                 }
13613                 return $data;
13614         }
13615
13616         function replace_urls($data, $tag, $attributes)
13617         {
13618                 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13619                 {
13620                         $elements = SimplePie_Misc::get_element($tag, $data);
13621                         foreach ($elements as $element)
13622                         {
13623                                 if (is_array($attributes))
13624                                 {
13625                                         foreach ($attributes as $attribute)
13626                                         {
13627                                                 if (isset($element['attribs'][$attribute]['data']))
13628                                                 {
13629                                                         $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13630                                                         $new_element = SimplePie_Misc::element_implode($element);
13631                                                         $data = str_replace($element['full'], $new_element, $data);
13632                                                         $element['full'] = $new_element;
13633                                                 }
13634                                         }
13635                                 }
13636                                 elseif (isset($element['attribs'][$attributes]['data']))
13637                                 {
13638                                         $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13639                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13640                                 }
13641                         }
13642                 }
13643                 return $data;
13644         }
13645
13646         function do_strip_htmltags($match)
13647         {
13648                 if ($this->encode_instead_of_strip)
13649                 {
13650                         if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13651                         {
13652                                 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13653                                 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13654                                 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13655                         }
13656                         else
13657                         {
13658                                 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13659                         }
13660                 }
13661                 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13662                 {
13663                         return $match[4];
13664                 }
13665                 else
13666                 {
13667                         return '';
13668                 }
13669         }
13670 }
13671
13672 ?>