]> git.wh0rd.org Git - tt-rss.git/blob - simplepie/simplepie.inc
78ccfb8b3c24c4f9c06689e236c898b4f2d76077
[tt-rss.git] / simplepie / simplepie.inc
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-2007, 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
37  * @copyright 2004-2007 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');
55
56 /**
57  * SimplePie Build
58  */
59 define('SIMPLEPIE_BUILD', 20080102221556);
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  * DC 1.0 Namespace
291  */
292 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
293
294 /**
295  * DC 1.1 Namespace
296  */
297 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
298
299 /**
300  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
301  */
302 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
303
304 /**
305  * GeoRSS Namespace
306  */
307 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
308
309 /**
310  * Media RSS Namespace
311  */
312 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
313
314 /**
315  * iTunes RSS Namespace
316  */
317 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
318
319 /**
320  * XHTML Namespace
321  */
322 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
323
324 /**
325  * IANA Link Relations Registry
326  */
327 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
328
329 /**
330  * Whether we're running on PHP5
331  */
332 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
333
334 /**
335  * No file source
336  */
337 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
338
339 /**
340  * Remote file source
341  */
342 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
343
344 /**
345  * Local file source
346  */
347 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
348
349 /**
350  * fsockopen() file source
351  */
352 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
353
354 /**
355  * cURL file source
356  */
357 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
358
359 /**
360  * file_get_contents() file source
361  */
362 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
363
364 /**
365  * SimplePie
366  *
367  * @package SimplePie
368  * @version "Razzleberry"
369  * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
370  * @author Ryan Parman
371  * @author Geoffrey Sneddon
372  * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
373  */
374 class SimplePie
375 {
376         /**
377          * @var array Raw data
378          * @access private
379          */
380         var $data = array();
381
382         /**
383          * @var mixed Error string
384          * @access private
385          */
386         var $error;
387
388         /**
389          * @var object Instance of SimplePie_Sanitize (or other class)
390          * @see SimplePie::set_sanitize_class()
391          * @access private
392          */
393         var $sanitize;
394
395         /**
396          * @var string SimplePie Useragent
397          * @see SimplePie::set_useragent()
398          * @access private
399          */
400         var $useragent = SIMPLEPIE_USERAGENT;
401
402         /**
403          * @var string Feed URL
404          * @see SimplePie::set_feed_url()
405          * @access private
406          */
407         var $feed_url;
408
409         /**
410          * @var object Instance of SimplePie_File to use as a feed
411          * @see SimplePie::set_file()
412          * @access private
413          */
414         var $file;
415
416         /**
417          * @var string Raw feed data
418          * @see SimplePie::set_raw_data()
419          * @access private
420          */
421         var $raw_data;
422
423         /**
424          * @var int Timeout for fetching remote files
425          * @see SimplePie::set_timeout()
426          * @access private
427          */
428         var $timeout = 10;
429
430         /**
431          * @var bool Forces fsockopen() to be used for remote files instead
432          * of cURL, even if a new enough version is installed
433          * @see SimplePie::force_fsockopen()
434          * @access private
435          */
436         var $force_fsockopen = false;
437
438         /**
439          * @var bool Force the given data/URL to be treated as a feed no matter what
440          * it appears like
441          * @see SimplePie::force_feed()
442          * @access private
443          */
444         var $force_feed = false;
445
446         /**
447          * @var bool Enable/Disable XML dump
448          * @see SimplePie::enable_xml_dump()
449          * @access private
450          */
451         var $xml_dump = false;
452
453         /**
454          * @var bool Enable/Disable Caching
455          * @see SimplePie::enable_cache()
456          * @access private
457          */
458         var $cache = true;
459
460         /**
461          * @var int Cache duration (in seconds)
462          * @see SimplePie::set_cache_duration()
463          * @access private
464          */
465         var $cache_duration = 3600;
466
467         /**
468          * @var int Auto-discovery cache duration (in seconds)
469          * @see SimplePie::set_autodiscovery_cache_duration()
470          * @access private
471          */
472         var $autodiscovery_cache_duration = 604800; // 7 Days.
473
474         /**
475          * @var string Cache location (relative to executing script)
476          * @see SimplePie::set_cache_location()
477          * @access private
478          */
479         var $cache_location = './cache';
480
481         /**
482          * @var string Function that creates the cache filename
483          * @see SimplePie::set_cache_name_function()
484          * @access private
485          */
486         var $cache_name_function = 'md5';
487
488         /**
489          * @var bool Reorder feed by date descending
490          * @see SimplePie::enable_order_by_date()
491          * @access private
492          */
493         var $order_by_date = true;
494
495         /**
496          * @var mixed Force input encoding to be set to the follow value
497          * (false, or anything type-cast to false, disables this feature)
498          * @see SimplePie::set_input_encoding()
499          * @access private
500          */
501         var $input_encoding = false;
502
503         /**
504          * @var int Feed Autodiscovery Level
505          * @see SimplePie::set_autodiscovery_level()
506          * @access private
507          */
508         var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
509
510         /**
511          * @var string Class used for caching feeds
512          * @see SimplePie::set_cache_class()
513          * @access private
514          */
515         var $cache_class = 'SimplePie_Cache';
516
517         /**
518          * @var string Class used for locating feeds
519          * @see SimplePie::set_locator_class()
520          * @access private
521          */
522         var $locator_class = 'SimplePie_Locator';
523
524         /**
525          * @var string Class used for parsing feeds
526          * @see SimplePie::set_parser_class()
527          * @access private
528          */
529         var $parser_class = 'SimplePie_Parser';
530
531         /**
532          * @var string Class used for fetching feeds
533          * @see SimplePie::set_file_class()
534          * @access private
535          */
536         var $file_class = 'SimplePie_File';
537
538         /**
539          * @var string Class used for items
540          * @see SimplePie::set_item_class()
541          * @access private
542          */
543         var $item_class = 'SimplePie_Item';
544
545         /**
546          * @var string Class used for authors
547          * @see SimplePie::set_author_class()
548          * @access private
549          */
550         var $author_class = 'SimplePie_Author';
551
552         /**
553          * @var string Class used for categories
554          * @see SimplePie::set_category_class()
555          * @access private
556          */
557         var $category_class = 'SimplePie_Category';
558
559         /**
560          * @var string Class used for enclosures
561          * @see SimplePie::set_enclosures_class()
562          * @access private
563          */
564         var $enclosure_class = 'SimplePie_Enclosure';
565
566         /**
567          * @var string Class used for Media RSS <media:text> captions
568          * @see SimplePie::set_caption_class()
569          * @access private
570          */
571         var $caption_class = 'SimplePie_Caption';
572
573         /**
574          * @var string Class used for Media RSS <media:copyright>
575          * @see SimplePie::set_copyright_class()
576          * @access private
577          */
578         var $copyright_class = 'SimplePie_Copyright';
579
580         /**
581          * @var string Class used for Media RSS <media:credit>
582          * @see SimplePie::set_credit_class()
583          * @access private
584          */
585         var $credit_class = 'SimplePie_Credit';
586
587         /**
588          * @var string Class used for Media RSS <media:rating>
589          * @see SimplePie::set_rating_class()
590          * @access private
591          */
592         var $rating_class = 'SimplePie_Rating';
593
594         /**
595          * @var string Class used for Media RSS <media:restriction>
596          * @see SimplePie::set_restriction_class()
597          * @access private
598          */
599         var $restriction_class = 'SimplePie_Restriction';
600
601         /**
602          * @var string Class used for content-type sniffing
603          * @see SimplePie::set_content_type_sniffer_class()
604          * @access private
605          */
606         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
607
608         /**
609          * @var string Class used for item sources.
610          * @see SimplePie::set_source_class()
611          * @access private
612          */
613         var $source_class = 'SimplePie_Source';
614
615         /**
616          * @var mixed Set javascript query string parameter (false, or
617          * anything type-cast to false, disables this feature)
618          * @see SimplePie::set_javascript()
619          * @access private
620          */
621         var $javascript = 'js';
622
623         /**
624          * @var int Maximum number of feeds to check with autodiscovery
625          * @see SimplePie::set_max_checked_feeds()
626          * @access private
627          */
628         var $max_checked_feeds = 10;
629
630         /**
631          * @var string Web-accessible path to the handler_favicon.php file.
632          * @see SimplePie::set_favicon_handler()
633          * @access private
634          */
635         var $favicon_handler = '';
636
637         /**
638          * @var string Web-accessible path to the handler_image.php file.
639          * @see SimplePie::set_image_handler()
640          * @access private
641          */
642         var $image_handler = '';
643
644         /**
645          * @var array Stores the URLs when multiple feeds are being initialized.
646          * @see SimplePie::set_feed_url()
647          * @access private
648          */
649         var $multifeed_url = array();
650
651         /**
652          * @var array Stores SimplePie objects when multiple feeds initialized.
653          * @access private
654          */
655         var $multifeed_objects = array();
656
657         /**
658          * @var array Stores the get_object_vars() array for use with multifeeds.
659          * @see SimplePie::set_feed_url()
660          * @access private
661          */
662         var $config_settings = null;
663
664         /**
665          * @var integer Stores the number of items to return per-feed with multifeeds.
666          * @see SimplePie::set_item_limit()
667          * @access private
668          */
669         var $item_limit = 0;
670
671         /**
672          * @var array Stores the default attributes to be stripped by strip_attributes().
673          * @see SimplePie::strip_attributes()
674          * @access private
675          */
676         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
677
678         /**
679          * @var array Stores the default tags to be stripped by strip_htmltags().
680          * @see SimplePie::strip_htmltags()
681          * @access private
682          */
683         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
684
685         /**
686          * The SimplePie class contains feed level data and options
687          *
688          * There are two ways that you can create a new SimplePie object. The first
689          * is by passing a feed URL as a parameter to the SimplePie constructor
690          * (as well as optionally setting the cache location and cache expiry). This
691          * will initialise the whole feed with all of the default settings, and you
692          * can begin accessing methods and properties immediately.
693          *
694          * The second way is to create the SimplePie object with no parameters
695          * at all. This will enable you to set configuration options. After setting
696          * them, you must initialise the feed using $feed->init(). At that point the
697          * object's methods and properties will be available to you. This format is
698          * what is used throughout this documentation.
699          *
700          * @access public
701          * @since 1.0 Preview Release
702          * @param string $feed_url This is the URL you want to parse.
703          * @param string $cache_location This is where you want the cache to be stored.
704          * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
705          */
706         function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
707         {
708                 // Other objects, instances created here so we can set options on them
709                 $this->sanitize =& new SimplePie_Sanitize;
710
711                 // Set options if they're passed to the constructor
712                 if ($cache_location !== null)
713                 {
714                         $this->set_cache_location($cache_location);
715                 }
716
717                 if ($cache_duration !== null)
718                 {
719                         $this->set_cache_duration($cache_duration);
720                 }
721
722                 // Only init the script if we're passed a feed URL
723                 if ($feed_url !== null)
724                 {
725                         $this->set_feed_url($feed_url);
726                         $this->init();
727                 }
728         }
729
730         /**
731          * Used for converting object to a string
732          */
733         function __toString()
734         {
735                 return md5(serialize($this->data));
736         }
737         
738         /**
739          * Remove items that link back to this before destroying this object
740          */
741         function __destruct()
742         {
743                 if (!empty($this->data['items']))
744                 {
745                         foreach ($this->data['items'] as $item)
746                         {
747                                 $item->__destruct();
748                         }
749                         unset($this->data['items']);
750                 }
751                 if (!empty($this->data['ordered_items']))
752                 {
753                         foreach ($this->data['ordered_items'] as $item)
754                         {
755                                 $item->__destruct();
756                         }
757                         unset($this->data['ordered_items']);
758                 }
759         }
760         
761         /**
762          * Force the given data/URL to be treated as a feed no matter what it
763          * appears like
764          *
765          * @access public
766          * @since 1.1
767          * @param bool $enable Force the given data/URL to be treated as a feed
768          */
769         function force_feed($enable = false)
770         {
771                 $this->force_feed = (bool) $enable;
772         }
773
774         /**
775          * This is the URL of the feed you want to parse.
776          *
777          * This allows you to enter the URL of the feed you want to parse, or the
778          * website you want to try to use auto-discovery on. This takes priority
779          * over any set raw data.
780          *
781          * You can set multiple feeds to mash together by passing an array instead
782          * of a string for the $url. Remember that with each additional feed comes
783          * additional processing and resources.
784          *
785          * @access public
786          * @since 1.0 Preview Release
787          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
788          * @see SimplePie::set_raw_data()
789          */
790         function set_feed_url($url)
791         {
792                 if (is_array($url))
793                 {
794                         $this->multifeed_url = array();
795                         foreach ($url as $value)
796                         {
797                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
798                         }
799                 }
800                 else
801                 {
802                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
803                 }
804         }
805
806         /**
807          * Provides an instance of SimplePie_File to use as a feed
808          *
809          * @access public
810          * @param object &$file Instance of SimplePie_File (or subclass)
811          * @return bool True on success, false on failure
812          */
813         function set_file(&$file)
814         {
815                 if (is_a($file, 'SimplePie_File'))
816                 {
817                         $this->feed_url = $file->url;
818                         $this->file =& $file;
819                         return true;
820                 }
821                 return false;
822         }
823
824         /**
825          * Allows you to use a string of RSS/Atom data instead of a remote feed.
826          *
827          * If you have a feed available as a string in PHP, you can tell SimplePie
828          * to parse that data string instead of a remote feed. Any set feed URL
829          * takes precedence.
830          *
831          * @access public
832          * @since 1.0 Beta 3
833          * @param string $data RSS or Atom data as a string.
834          * @see SimplePie::set_feed_url()
835          */
836         function set_raw_data($data)
837         {
838                 $this->raw_data = trim($data);
839         }
840
841         /**
842          * Allows you to override the default timeout for fetching remote feeds.
843          *
844          * This allows you to change the maximum time the feed's server to respond
845          * and send the feed back.
846          *
847          * @access public
848          * @since 1.0 Beta 3
849          * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
850          */
851         function set_timeout($timeout = 10)
852         {
853                 $this->timeout = (int) $timeout;
854         }
855
856         /**
857          * Forces SimplePie to use fsockopen() instead of the preferred cURL
858          * functions.
859          *
860          * @access public
861          * @since 1.0 Beta 3
862          * @param bool $enable Force fsockopen() to be used
863          */
864         function force_fsockopen($enable = false)
865         {
866                 $this->force_fsockopen = (bool) $enable;
867         }
868
869         /**
870          * Outputs the raw XML content of the feed, after it has gone through
871          * SimplePie's filters.
872          *
873          * Used only for debugging, this function will output the XML content as
874          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
875          * before trying to parse it. Many parts of the feed are re-written in
876          * memory, and in the end, you have a parsable feed. XML dump shows you the
877          * actual XML that SimplePie tries to parse, which may or may not be very
878          * different from the original feed.
879          *
880          * @access public
881          * @since 1.0 Preview Release
882          * @param bool $enable Enable XML dump
883          */
884         function enable_xml_dump($enable = false)
885         {
886                 $this->xml_dump = (bool) $enable;
887         }
888
889         /**
890          * Enables/disables caching in SimplePie.
891          *
892          * This option allows you to disable caching all-together in SimplePie.
893          * However, disabling the cache can lead to longer load times.
894          *
895          * @access public
896          * @since 1.0 Preview Release
897          * @param bool $enable Enable caching
898          */
899         function enable_cache($enable = true)
900         {
901                 $this->cache = (bool) $enable;
902         }
903
904         /**
905          * Set the length of time (in seconds) that the contents of a feed
906          * will be cached.
907          *
908          * @access public
909          * @param int $seconds The feed content cache duration.
910          */
911         function set_cache_duration($seconds = 3600)
912         {
913                 $this->cache_duration = (int) $seconds;
914         }
915
916         /**
917          * Set the length of time (in seconds) that the autodiscovered feed
918          * URL will be cached.
919          *
920          * @access public
921          * @param int $seconds The autodiscovered feed URL cache duration.
922          */
923         function set_autodiscovery_cache_duration($seconds = 604800)
924         {
925                 $this->autodiscovery_cache_duration = (int) $seconds;
926         }
927
928         /**
929          * Set the file system location where the cached files should be stored.
930          *
931          * @access public
932          * @param string $location The file system location.
933          */
934         function set_cache_location($location = './cache')
935         {
936                 $this->cache_location = (string) $location;
937         }
938
939         /**
940          * Determines whether feed items should be sorted into reverse chronological order.
941          *
942          * @access public
943          * @param bool $enable Sort as reverse chronological order.
944          */
945         function enable_order_by_date($enable = true)
946         {
947                 $this->order_by_date = (bool) $enable;
948         }
949
950         /**
951          * Allows you to override the character encoding reported by the feed.
952          *
953          * @access public
954          * @param string $encoding Character encoding.
955          */
956         function set_input_encoding($encoding = false)
957         {
958                 if ($encoding)
959                 {
960                         $this->input_encoding = (string) $encoding;
961                 }
962                 else
963                 {
964                         $this->input_encoding = false;
965                 }
966         }
967
968         /**
969          * Set how much feed autodiscovery to do
970          *
971          * @access public
972          * @see SIMPLEPIE_LOCATOR_NONE
973          * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
974          * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
975          * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
976          * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
977          * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
978          * @see SIMPLEPIE_LOCATOR_ALL
979          * @param int $level Feed Autodiscovery Level (level can be a
980          * combination of the above constants, see bitwise OR operator)
981          */
982         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
983         {
984                 $this->autodiscovery = (int) $level;
985         }
986
987         /**
988          * Allows you to change which class SimplePie uses for caching.
989          * Useful when you are overloading or extending SimplePie's default classes.
990          *
991          * @access public
992          * @param string $class Name of custom class.
993          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
994          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
995          */
996         function set_cache_class($class = 'SimplePie_Cache')
997         {
998                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
999                 {
1000                         $this->cache_class = $class;
1001                         return true;
1002                 }
1003                 return false;
1004         }
1005
1006         /**
1007          * Allows you to change which class SimplePie uses for auto-discovery.
1008          * Useful when you are overloading or extending SimplePie's default classes.
1009          *
1010          * @access public
1011          * @param string $class Name of custom class.
1012          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1013          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1014          */
1015         function set_locator_class($class = 'SimplePie_Locator')
1016         {
1017                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1018                 {
1019                         $this->locator_class = $class;
1020                         return true;
1021                 }
1022                 return false;
1023         }
1024
1025         /**
1026          * Allows you to change which class SimplePie uses for XML parsing.
1027          * Useful when you are overloading or extending SimplePie's default classes.
1028          *
1029          * @access public
1030          * @param string $class Name of custom class.
1031          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1032          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1033          */
1034         function set_parser_class($class = 'SimplePie_Parser')
1035         {
1036                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1037                 {
1038                         $this->parser_class = $class;
1039                         return true;
1040                 }
1041                 return false;
1042         }
1043
1044         /**
1045          * Allows you to change which class SimplePie uses for remote file fetching.
1046          * Useful when you are overloading or extending SimplePie's default classes.
1047          *
1048          * @access public
1049          * @param string $class Name of custom class.
1050          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1051          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1052          */
1053         function set_file_class($class = 'SimplePie_File')
1054         {
1055                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1056                 {
1057                         $this->file_class = $class;
1058                         return true;
1059                 }
1060                 return false;
1061         }
1062
1063         /**
1064          * Allows you to change which class SimplePie uses for data sanitization.
1065          * Useful when you are overloading or extending SimplePie's default classes.
1066          *
1067          * @access public
1068          * @param string $class Name of custom class.
1069          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1070          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1071          */
1072         function set_sanitize_class($class = 'SimplePie_Sanitize')
1073         {
1074                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1075                 {
1076                         $this->sanitize =& new $class;
1077                         return true;
1078                 }
1079                 return false;
1080         }
1081
1082         /**
1083          * Allows you to change which class SimplePie uses for handling feed items.
1084          * Useful when you are overloading or extending SimplePie's default classes.
1085          *
1086          * @access public
1087          * @param string $class Name of custom class.
1088          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1089          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1090          */
1091         function set_item_class($class = 'SimplePie_Item')
1092         {
1093                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1094                 {
1095                         $this->item_class = $class;
1096                         return true;
1097                 }
1098                 return false;
1099         }
1100
1101         /**
1102          * Allows you to change which class SimplePie uses for handling author data.
1103          * Useful when you are overloading or extending SimplePie's default classes.
1104          *
1105          * @access public
1106          * @param string $class Name of custom class.
1107          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1108          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1109          */
1110         function set_author_class($class = 'SimplePie_Author')
1111         {
1112                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1113                 {
1114                         $this->author_class = $class;
1115                         return true;
1116                 }
1117                 return false;
1118         }
1119
1120         /**
1121          * Allows you to change which class SimplePie uses for handling category data.
1122          * Useful when you are overloading or extending SimplePie's default classes.
1123          *
1124          * @access public
1125          * @param string $class Name of custom class.
1126          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1127          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1128          */
1129         function set_category_class($class = 'SimplePie_Category')
1130         {
1131                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1132                 {
1133                         $this->category_class = $class;
1134                         return true;
1135                 }
1136                 return false;
1137         }
1138
1139         /**
1140          * Allows you to change which class SimplePie uses for feed enclosures.
1141          * Useful when you are overloading or extending SimplePie's default classes.
1142          *
1143          * @access public
1144          * @param string $class Name of custom class.
1145          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1146          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1147          */
1148         function set_enclosure_class($class = 'SimplePie_Enclosure')
1149         {
1150                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1151                 {
1152                         $this->enclosure_class = $class;
1153                         return true;
1154                 }
1155                 return false;
1156         }
1157
1158         /**
1159          * Allows you to change which class SimplePie uses for <media:text> captions
1160          * Useful when you are overloading or extending SimplePie's default classes.
1161          *
1162          * @access public
1163          * @param string $class Name of custom class.
1164          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1165          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1166          */
1167         function set_caption_class($class = 'SimplePie_Caption')
1168         {
1169                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1170                 {
1171                         $this->caption_class = $class;
1172                         return true;
1173                 }
1174                 return false;
1175         }
1176
1177         /**
1178          * Allows you to change which class SimplePie uses for <media:copyright>
1179          * Useful when you are overloading or extending SimplePie's default classes.
1180          *
1181          * @access public
1182          * @param string $class Name of custom class.
1183          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1184          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1185          */
1186         function set_copyright_class($class = 'SimplePie_Copyright')
1187         {
1188                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1189                 {
1190                         $this->copyright_class = $class;
1191                         return true;
1192                 }
1193                 return false;
1194         }
1195
1196         /**
1197          * Allows you to change which class SimplePie uses for <media:credit>
1198          * Useful when you are overloading or extending SimplePie's default classes.
1199          *
1200          * @access public
1201          * @param string $class Name of custom class.
1202          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1203          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1204          */
1205         function set_credit_class($class = 'SimplePie_Credit')
1206         {
1207                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1208                 {
1209                         $this->credit_class = $class;
1210                         return true;
1211                 }
1212                 return false;
1213         }
1214
1215         /**
1216          * Allows you to change which class SimplePie uses for <media:rating>
1217          * Useful when you are overloading or extending SimplePie's default classes.
1218          *
1219          * @access public
1220          * @param string $class Name of custom class.
1221          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1222          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1223          */
1224         function set_rating_class($class = 'SimplePie_Rating')
1225         {
1226                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1227                 {
1228                         $this->rating_class = $class;
1229                         return true;
1230                 }
1231                 return false;
1232         }
1233
1234         /**
1235          * Allows you to change which class SimplePie uses for <media:restriction>
1236          * Useful when you are overloading or extending SimplePie's default classes.
1237          *
1238          * @access public
1239          * @param string $class Name of custom class.
1240          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1241          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1242          */
1243         function set_restriction_class($class = 'SimplePie_Restriction')
1244         {
1245                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1246                 {
1247                         $this->restriction_class = $class;
1248                         return true;
1249                 }
1250                 return false;
1251         }
1252
1253         /**
1254          * Allows you to change which class SimplePie uses for content-type sniffing.
1255          * Useful when you are overloading or extending SimplePie's default classes.
1256          *
1257          * @access public
1258          * @param string $class Name of custom class.
1259          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1260          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1261          */
1262         function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1263         {
1264                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1265                 {
1266                         $this->content_type_sniffer_class = $class;
1267                         return true;
1268                 }
1269                 return false;
1270         }
1271
1272         /**
1273          * Allows you to change which class SimplePie uses item sources.
1274          * Useful when you are overloading or extending SimplePie's default classes.
1275          *
1276          * @access public
1277          * @param string $class Name of custom class.
1278          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1279          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1280          */
1281         function set_source_class($class = 'SimplePie_Source')
1282         {
1283                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1284                 {
1285                         $this->source_class = $class;
1286                         return true;
1287                 }
1288                 return false;
1289         }
1290
1291         /**
1292          * Allows you to override the default user agent string.
1293          *
1294          * @access public
1295          * @param string $ua New user agent string.
1296          */
1297         function set_useragent($ua = SIMPLEPIE_USERAGENT)
1298         {
1299                 $this->useragent = (string) $ua;
1300         }
1301
1302         /**
1303          * Set callback function to create cache filename with
1304          *
1305          * @access public
1306          * @param mixed $function Callback function
1307          */
1308         function set_cache_name_function($function = 'md5')
1309         {
1310                 if (is_callable($function))
1311                 {
1312                         $this->cache_name_function = $function;
1313                 }
1314         }
1315
1316         /**
1317          * Set javascript query string parameter
1318          *
1319          * @access public
1320          * @param mixed $get Javascript query string parameter
1321          */
1322         function set_javascript($get = 'js')
1323         {
1324                 if ($get)
1325                 {
1326                         $this->javascript = (string) $get;
1327                 }
1328                 else
1329                 {
1330                         $this->javascript = false;
1331                 }
1332         }
1333
1334         /**
1335          * Set options to make SP as fast as possible.  Forgoes a
1336          * substantial amount of data sanitization in favor of speed.
1337          *
1338          * @access public
1339          * @param bool $set Whether to set them or not
1340          */
1341         function set_stupidly_fast($set = false)
1342         {
1343                 if ($set)
1344                 {
1345                         $this->enable_order_by_date(false);
1346                         $this->remove_div(false);
1347                         $this->strip_comments(false);
1348                         $this->strip_htmltags(false);
1349                         $this->strip_attributes(false);
1350                         $this->set_image_handler(false);
1351                 }
1352         }
1353
1354         /**
1355          * Set maximum number of feeds to check with autodiscovery
1356          *
1357          * @access public
1358          * @param int $max Maximum number of feeds to check
1359          */
1360         function set_max_checked_feeds($max = 10)
1361         {
1362                 $this->max_checked_feeds = (int) $max;
1363         }
1364
1365         function remove_div($enable = true)
1366         {
1367                 $this->sanitize->remove_div($enable);
1368         }
1369
1370         function strip_htmltags($tags = '', $encode = null)
1371         {
1372                 if ($tags === '')
1373                 {
1374                         $tags = $this->strip_htmltags;
1375                 }
1376                 $this->sanitize->strip_htmltags($tags);
1377                 if ($encode !== null)
1378                 {
1379                         $this->sanitize->encode_instead_of_strip($tags);
1380                 }
1381         }
1382
1383         function encode_instead_of_strip($enable = true)
1384         {
1385                 $this->sanitize->encode_instead_of_strip($enable);
1386         }
1387
1388         function strip_attributes($attribs = '')
1389         {
1390                 if ($attribs === '')
1391                 {
1392                         $attribs = $this->strip_attributes;
1393                 }
1394                 $this->sanitize->strip_attributes($attribs);
1395         }
1396
1397         function set_output_encoding($encoding = 'UTF-8')
1398         {
1399                 $this->sanitize->set_output_encoding($encoding);
1400         }
1401
1402         function strip_comments($strip = false)
1403         {
1404                 $this->sanitize->strip_comments($strip);
1405         }
1406
1407         /**
1408          * Set element/attribute key/value pairs of HTML attributes
1409          * containing URLs that need to be resolved relative to the feed
1410          *
1411          * @access public
1412          * @since 1.0
1413          * @param array $element_attribute Element/attribute key/value pairs
1414          */
1415         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'))
1416         {
1417                 $this->sanitize->set_url_replacements($element_attribute);
1418         }
1419
1420         /**
1421          * Set the handler to enable the display of cached favicons.
1422          *
1423          * @access public
1424          * @param str $page Web-accessible path to the handler_favicon.php file.
1425          * @param str $qs The query string that the value should be passed to.
1426          */
1427         function set_favicon_handler($page = false, $qs = 'i')
1428         {
1429                 if ($page != false)
1430                 {
1431                         $this->favicon_handler = $page . '?' . $qs . '=';
1432                 }
1433                 else
1434                 {
1435                         $this->favicon_handler = '';
1436                 }
1437         }
1438
1439         /**
1440          * Set the handler to enable the display of cached images.
1441          *
1442          * @access public
1443          * @param str $page Web-accessible path to the handler_image.php file.
1444          * @param str $qs The query string that the value should be passed to.
1445          */
1446         function set_image_handler($page = false, $qs = 'i')
1447         {
1448                 if ($page != false)
1449                 {
1450                         $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1451                 }
1452                 else
1453                 {
1454                         $this->image_handler = '';
1455                 }
1456         }
1457
1458         /**
1459          * Set the limit for items returned per-feed with multifeeds.
1460          *
1461          * @access public
1462          * @param integer $limit The maximum number of items to return.
1463          */
1464         function set_item_limit($limit = 0)
1465         {
1466                 $this->item_limit = (int) $limit;
1467         }
1468
1469         function init()
1470         {
1471                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1472                 {
1473                         return false;
1474                 }
1475                 if (isset($_GET[$this->javascript]))
1476                 {
1477                         if (function_exists('ob_gzhandler'))
1478                         {
1479                                 ob_start('ob_gzhandler');
1480                         }
1481                         header('Content-type: text/javascript; charset: UTF-8');
1482                         header('Cache-Control: must-revalidate');
1483                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1484                         ?>
1485 function embed_odeo(link) {
1486         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>');
1487 }
1488
1489 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1490         if (placeholder != '') {
1491                 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>');
1492         }
1493         else {
1494                 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>');
1495         }
1496 }
1497
1498 function embed_flash(bgcolor, width, height, link, loop, type) {
1499         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>');
1500 }
1501
1502 function embed_flv(width, height, link, placeholder, loop, player) {
1503         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>');
1504 }
1505
1506 function embed_wmedia(width, height, link) {
1507         document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1508 }
1509                         <?php
1510                         exit;
1511                 }
1512
1513                 // Pass whatever was set with config options over to the sanitizer.
1514                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1515                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1516
1517                 if ($this->feed_url !== null || $this->raw_data !== null)
1518                 {
1519                         $this->data = array();
1520                         $this->multifeed_objects = array();
1521                         $cache = false;
1522
1523                         if ($this->feed_url !== null)
1524                         {
1525                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1526                                 // Decide whether to enable caching
1527                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1528                                 {
1529                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1530                                 }
1531                                 // If it's enabled and we don't want an XML dump, use the cache
1532                                 if ($cache && !$this->xml_dump)
1533                                 {
1534                                         // Load the Cache
1535                                         $this->data = $cache->load();
1536                                         if (!empty($this->data))
1537                                         {
1538                                                 // If the cache is for an outdated build of SimplePie
1539                                                 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1540                                                 {
1541                                                         $cache->unlink();
1542                                                         $this->data = array();
1543                                                 }
1544                                                 // If we've hit a collision just rerun it with caching disabled
1545                                                 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1546                                                 {
1547                                                         $cache = false;
1548                                                         $this->data = array();
1549                                                 }
1550                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1551                                                 elseif (isset($this->data['feed_url']))
1552                                                 {
1553                                                         // If the autodiscovery cache is still valid use it.
1554                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1555                                                         {
1556                                                                 // Do not need to do feed autodiscovery yet.
1557                                                                 if ($this->data['feed_url'] == $this->data['url'])
1558                                                                 {
1559                                                                         $cache->unlink();
1560                                                                         $this->data = array();
1561                                                                 }
1562                                                                 else
1563                                                                 {
1564                                                                         $this->set_feed_url($this->data['feed_url']);
1565                                                                         return $this->init();
1566                                                                 }
1567                                                         }
1568                                                 }
1569                                                 // Check if the cache has been updated
1570                                                 elseif ($cache->mtime() + $this->cache_duration < time())
1571                                                 {
1572                                                         // If we have last-modified and/or etag set
1573                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1574                                                         {
1575                                                                 $headers = array();
1576                                                                 if (isset($this->data['headers']['last-modified']))
1577                                                                 {
1578                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1579                                                                 }
1580                                                                 if (isset($this->data['headers']['etag']))
1581                                                                 {
1582                                                                         $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1583                                                                 }
1584                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1585                                                                 if ($file->success)
1586                                                                 {
1587                                                                         if ($file->status_code == 304)
1588                                                                         {
1589                                                                                 $cache->touch();
1590                                                                                 return true;
1591                                                                         }
1592                                                                         else
1593                                                                         {
1594                                                                                 $headers = $file->headers;
1595                                                                         }
1596                                                                 }
1597                                                                 else
1598                                                                 {
1599                                                                         unset($file);
1600                                                                 }
1601                                                         }
1602                                                 }
1603                                                 // If the cache is still valid, just return true
1604                                                 else
1605                                                 {
1606                                                         return true;
1607                                                 }
1608                                         }
1609                                         // If the cache is empty, delete it
1610                                         else
1611                                         {
1612                                                 $cache->unlink();
1613                                                 $this->data = array();
1614                                         }
1615                                 }
1616                                 // 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.
1617                                 if (!isset($file))
1618                                 {
1619                                         if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1620                                         {
1621                                                 $file =& $this->file;
1622                                         }
1623                                         else
1624                                         {
1625                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1626                                         }
1627                                 }
1628                                 // If the file connection has an error, set SimplePie::error to that and quit
1629                                 if (!$file->success)
1630                                 {
1631                                         $this->error = $file->error;
1632                                         if (!empty($this->data))
1633                                         {
1634                                                 return true;
1635                                         }
1636                                         else
1637                                         {
1638                                                 return false;
1639                                         }
1640                                 }
1641
1642                                 if (!$this->force_feed)
1643                                 {
1644                                         // Check if the supplied URL is a feed, if it isn't, look for it.
1645                                         $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1646                                         if (!$locate->is_feed($file))
1647                                         {
1648                                                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1649                                                 unset($file);
1650                                                 if ($file = $locate->find($this->autodiscovery))
1651                                                 {
1652                                                         if ($cache)
1653                                                         {
1654                                                                 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1655                                                                 if (!$cache->save($this))
1656                                                                 {
1657                                                                         trigger_error("$cache->name is not writeable", E_USER_WARNING);
1658                                                                 }
1659                                                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1660                                                         }
1661                                                         $this->feed_url = $file->url;
1662                                                 }
1663                                                 else
1664                                                 {
1665                                                         $this->error = "A feed could not be found at $this->feed_url";
1666                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1667                                                         return false;
1668                                                 }
1669                                         }
1670                                         $locate = null;
1671                                 }
1672
1673                                 $headers = $file->headers;
1674                                 $data = $file->body;
1675                                 $sniffer = new $this->content_type_sniffer_class($file);
1676                                 $sniffed = $sniffer->get_type();
1677                         }
1678                         else
1679                         {
1680                                 $data = $this->raw_data;
1681                         }
1682                         
1683                         // Set up array of possible encodings
1684                         $encodings = array();
1685
1686                         // First check to see if input has been overridden.
1687                         if ($this->input_encoding !== false)
1688                         {
1689                                 $encodings[] = $this->input_encoding;
1690                         }
1691                         
1692                         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1693                         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1694                         
1695                         // RFC 3023 (only applies to sniffed content)
1696                         if (isset($sniffed))
1697                         {
1698                                 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1699                                 {
1700                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1701                                         {
1702                                                 $encodings[] = strtoupper($charset[1]);
1703                                         }
1704                                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1705                                         $encodings[] = 'UTF-8';
1706                                 }
1707                                 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1708                                 {
1709                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1710                                         {
1711                                                 $encodings[] = $charset[1];
1712                                         }
1713                                         $encodings[] = 'US-ASCII';
1714                                 }
1715                                 // Text MIME-type default
1716                                 elseif (substr($sniffed, 0, 5) === 'text/')
1717                                 {
1718                                         $encodings[] = 'US-ASCII';
1719                                 }
1720                         }
1721                         
1722                         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1723                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1724                         $encodings[] = 'UTF-8';
1725                         $encodings[] = 'ISO-8859-1';
1726                         
1727                         // There's no point in trying an encoding twice
1728                         $encodings = array_unique($encodings);
1729                         
1730                         // If we want the XML, just output that with the most likely encoding and quit
1731                         if ($this->xml_dump)
1732                         {
1733                                 header('Content-type: text/xml; charset=' . $encodings[0]);
1734                                 echo $data;
1735                                 exit;
1736                         }
1737                         
1738                         // Loop through each possible encoding, till we return something, or run out of possibilities
1739                         foreach ($encodings as $encoding)
1740                         {
1741                                 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1742                                 $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1743
1744                                 // Create new parser
1745                                 $parser =& new $this->parser_class();
1746                                 
1747                                 // If it's parsed fine
1748                                 if ($parser->parse($utf8_data, 'UTF-8'))
1749                                 {
1750                                         $this->data = $parser->get_data();
1751                                         if (isset($this->data['child']))
1752                                         {
1753                                                 if (isset($headers))
1754                                                 {
1755                                                         $this->data['headers'] = $headers;
1756                                                 }
1757                                                 $this->data['build'] = SIMPLEPIE_BUILD;
1758         
1759                                                 // Cache the file if caching is enabled
1760                                                 if ($cache && !$cache->save($this))
1761                                                 {
1762                                                         trigger_error("$cache->name is not writeable", E_USER_WARNING);
1763                                                 }
1764                                                 return true;
1765                                         }
1766                                         else
1767                                         {
1768                                                 $this->error = "A feed could not be found at $this->feed_url";
1769                                                 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1770                                                 return false;
1771                                         }
1772                                 }
1773                         }
1774                         // We have an error, just set SimplePie::error to it and quit
1775                         $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1776                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1777                         return false;
1778                 }
1779                 elseif (!empty($this->multifeed_url))
1780                 {
1781                         $i = 0;
1782                         $success = 0;
1783                         $this->multifeed_objects = array();
1784                         foreach ($this->multifeed_url as $url)
1785                         {
1786                                 if (SIMPLEPIE_PHP5)
1787                                 {
1788                                         // This keyword needs to defy coding standards for PHP4 compatibility
1789                                         $this->multifeed_objects[$i] = clone($this);
1790                                 }
1791                                 else
1792                                 {
1793                                         $this->multifeed_objects[$i] = $this;
1794                                 }
1795                                 $this->multifeed_objects[$i]->set_feed_url($url);
1796                                 $success |= $this->multifeed_objects[$i]->init();
1797                                 $i++;
1798                         }
1799                         return (bool) $success;
1800                 }
1801                 else
1802                 {
1803                         return false;
1804                 }
1805         }
1806
1807         /**
1808          * Return the error message for the occured error
1809          *
1810          * @access public
1811          * @return string Error message
1812          */
1813         function error()
1814         {
1815                 return $this->error;
1816         }
1817
1818         function get_encoding()
1819         {
1820                 return $this->sanitize->output_encoding;
1821         }
1822
1823         function handle_content_type($mime = 'text/html')
1824         {
1825                 if (!headers_sent())
1826                 {
1827                         $header = "Content-type: $mime;";
1828                         if ($this->get_encoding())
1829                         {
1830                                 $header .= ' charset=' . $this->get_encoding();
1831                         }
1832                         else
1833                         {
1834                                 $header .= ' charset=UTF-8';
1835                         }
1836                         header($header);
1837                 }
1838         }
1839
1840         function get_type()
1841         {
1842                 if (!isset($this->data['type']))
1843                 {
1844                         $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1845                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1846                         {
1847                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1848                         }
1849                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1850                         {
1851                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1852                         }
1853                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1854                         {
1855                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1856                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1857                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1858                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1859                                 {
1860                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1861                                 }
1862                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1863                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1864                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1865                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1866                                 {
1867                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1868                                 }
1869                         }
1870                         elseif (isset($this->data['child']['']['rss']))
1871                         {
1872                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1873                                 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1874                                 {
1875                                         switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1876                                         {
1877                                                 case '0.91':
1878                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1879                                                         if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1880                                                         {
1881                                                                 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1882                                                                 {
1883                                                                         case '0':
1884                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1885                                                                                 break;
1886
1887                                                                         case '24':
1888                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1889                                                                                 break;
1890                                                                 }
1891                                                         }
1892                                                         break;
1893
1894                                                 case '0.92':
1895                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1896                                                         break;
1897
1898                                                 case '0.93':
1899                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1900                                                         break;
1901
1902                                                 case '0.94':
1903                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1904                                                         break;
1905
1906                                                 case '2.0':
1907                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1908                                                         break;
1909                                         }
1910                                 }
1911                         }
1912                         else
1913                         {
1914                                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1915                         }
1916                 }
1917                 return $this->data['type'];
1918         }
1919
1920         /**
1921          * Returns the URL for the favicon of the feed's website.
1922          *
1923          * @todo Cache atom:icon
1924          * @access public
1925          * @since 1.0
1926          */
1927         function get_favicon()
1928         {
1929                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1930                 {
1931                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1932                 }
1933                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1934                 {
1935                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1936
1937                         if ($this->cache && $this->favicon_handler)
1938                         {
1939                                 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1940                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1941
1942                                 if ($cache->load())
1943                                 {
1944                                         return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1945                                 }
1946                                 else
1947                                 {
1948                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1949
1950                                         if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1951                                         {
1952                                                 $sniffer = new $this->content_type_sniffer_class($file);
1953                                                 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1954                                                 {
1955                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1956                                                         {
1957                                                                 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1958                                                         }
1959                                                         else
1960                                                         {
1961                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1962                                                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1963                                                         }
1964                                                 }
1965                                         }
1966                                 }
1967                         }
1968                         else
1969                         {
1970                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1971                         }
1972                 }
1973                 return false;
1974         }
1975
1976         /**
1977          * @todo If we have a perm redirect we should return the new URL
1978          * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1979          * @todo Also, |atom:link|@rel=self
1980          */
1981         function subscribe_url()
1982         {
1983                 if ($this->feed_url !== null)
1984                 {
1985                         return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1986                 }
1987                 else
1988                 {
1989                         return null;
1990                 }
1991         }
1992
1993         function subscribe_feed()
1994         {
1995                 if ($this->feed_url !== null)
1996                 {
1997                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1998                 }
1999                 else
2000                 {
2001                         return null;
2002                 }
2003         }
2004
2005         function subscribe_outlook()
2006         {
2007                 if ($this->feed_url !== null)
2008                 {
2009                         return 'outlook' . $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_podcast()
2018         {
2019                 if ($this->feed_url !== null)
2020                 {
2021                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2022                 }
2023                 else
2024                 {
2025                         return null;
2026                 }
2027         }
2028
2029         function subscribe_itunes()
2030         {
2031                 if ($this->feed_url !== null)
2032                 {
2033                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2034                 }
2035                 else
2036                 {
2037                         return null;
2038                 }
2039         }
2040
2041         /**
2042          * Creates the subscribe_* methods' return data
2043          *
2044          * @access private
2045          * @param string $feed_url String to prefix to the feed URL
2046          * @param string $site_url String to prefix to the site URL (and
2047          * suffix to the feed URL)
2048          * @return mixed URL if feed exists, false otherwise
2049          */
2050         function subscribe_service($feed_url, $site_url = null)
2051         {
2052                 if ($this->subscribe_url())
2053                 {
2054                         $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2055                         if ($site_url !== null && $this->get_link() !== null)
2056                         {
2057                                 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2058                         }
2059                         return $return;
2060                 }
2061                 else
2062                 {
2063                         return null;
2064                 }
2065         }
2066
2067         function subscribe_aol()
2068         {
2069                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2070         }
2071
2072         function subscribe_bloglines()
2073         {
2074                 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2075         }
2076
2077         function subscribe_eskobo()
2078         {
2079                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2080         }
2081
2082         function subscribe_feedfeeds()
2083         {
2084                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2085         }
2086
2087         function subscribe_feedster()
2088         {
2089                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2090         }
2091
2092         function subscribe_google()
2093         {
2094                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2095         }
2096
2097         function subscribe_gritwire()
2098         {
2099                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2100         }
2101
2102         function subscribe_msn()
2103         {
2104                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2105         }
2106
2107         function subscribe_netvibes()
2108         {
2109                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2110         }
2111
2112         function subscribe_newsburst()
2113         {
2114                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2115         }
2116
2117         function subscribe_newsgator()
2118         {
2119                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2120         }
2121
2122         function subscribe_odeo()
2123         {
2124                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2125         }
2126
2127         function subscribe_podnova()
2128         {
2129                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2130         }
2131
2132         function subscribe_rojo()
2133         {
2134                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2135         }
2136
2137         function subscribe_yahoo()
2138         {
2139                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2140         }
2141
2142         function get_feed_tags($namespace, $tag)
2143         {
2144                 $type = $this->get_type();
2145                 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2146                 {
2147                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2148                         {
2149                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2150                         }
2151                 }
2152                 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2153                 {
2154                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2155                         {
2156                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2157                         }
2158                 }
2159                 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2160                 {
2161                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2162                         {
2163                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2164                         }
2165                 }
2166                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2167                 {
2168                         if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2169                         {
2170                                 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2171                         }
2172                 }
2173                 return null;
2174         }
2175
2176         function get_channel_tags($namespace, $tag)
2177         {
2178                 $type = $this->get_type();
2179                 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2180                 {
2181                         if ($return = $this->get_feed_tags($namespace, $tag))
2182                         {
2183                                 return $return;
2184                         }
2185                 }
2186                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2187                 {
2188                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2189                         {
2190                                 if (isset($channel[0]['child'][$namespace][$tag]))
2191                                 {
2192                                         return $channel[0]['child'][$namespace][$tag];
2193                                 }
2194                         }
2195                 }
2196                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2197                 {
2198                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2199                         {
2200                                 if (isset($channel[0]['child'][$namespace][$tag]))
2201                                 {
2202                                         return $channel[0]['child'][$namespace][$tag];
2203                                 }
2204                         }
2205                 }
2206                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2207                 {
2208                         if ($channel = $this->get_feed_tags('', 'channel'))
2209                         {
2210                                 if (isset($channel[0]['child'][$namespace][$tag]))
2211                                 {
2212                                         return $channel[0]['child'][$namespace][$tag];
2213                                 }
2214                         }
2215                 }
2216                 return null;
2217         }
2218
2219         function get_image_tags($namespace, $tag)
2220         {
2221                 $type = $this->get_type();
2222                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2223                 {
2224                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2225                         {
2226                                 if (isset($image[0]['child'][$namespace][$tag]))
2227                                 {
2228                                         return $image[0]['child'][$namespace][$tag];
2229                                 }
2230                         }
2231                 }
2232                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2233                 {
2234                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2235                         {
2236                                 if (isset($image[0]['child'][$namespace][$tag]))
2237                                 {
2238                                         return $image[0]['child'][$namespace][$tag];
2239                                 }
2240                         }
2241                 }
2242                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2243                 {
2244                         if ($image = $this->get_channel_tags('', 'image'))
2245                         {
2246                                 if (isset($image[0]['child'][$namespace][$tag]))
2247                                 {
2248                                         return $image[0]['child'][$namespace][$tag];
2249                                 }
2250                         }
2251                 }
2252                 return null;
2253         }
2254
2255         function get_base($element = array())
2256         {
2257                 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2258                 {
2259                         return $element['xml_base'];
2260                 }
2261                 elseif ($this->get_link() !== null)
2262                 {
2263                         return $this->get_link();
2264                 }
2265                 else
2266                 {
2267                         return $this->subscribe_url();
2268                 }
2269         }
2270
2271         function sanitize($data, $type, $base = '')
2272         {
2273                 return $this->sanitize->sanitize($data, $type, $base);
2274         }
2275
2276         function get_title()
2277         {
2278                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2279                 {
2280                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2281                 }
2282                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2283                 {
2284                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2285                 }
2286                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2287                 {
2288                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2289                 }
2290                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2291                 {
2292                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2293                 }
2294                 elseif ($return = $this->get_channel_tags('', 'title'))
2295                 {
2296                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2297                 }
2298                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2299                 {
2300                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2301                 }
2302                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2303                 {
2304                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2305                 }
2306                 else
2307                 {
2308                         return null;
2309                 }
2310         }
2311
2312         function get_category($key = 0)
2313         {
2314                 $categories = $this->get_categories();
2315                 if (isset($categories[$key]))
2316                 {
2317                         return $categories[$key];
2318                 }
2319                 else
2320                 {
2321                         return null;
2322                 }
2323         }
2324
2325         function get_categories()
2326         {
2327                 $categories = array();
2328
2329                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2330                 {
2331                         $term = null;
2332                         $scheme = null;
2333                         $label = null;
2334                         if (isset($category['attribs']['']['term']))
2335                         {
2336                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2337                         }
2338                         if (isset($category['attribs']['']['scheme']))
2339                         {
2340                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2341                         }
2342                         if (isset($category['attribs']['']['label']))
2343                         {
2344                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2345                         }
2346                         $categories[] =& new $this->category_class($term, $scheme, $label);
2347                 }
2348                 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2349                 {
2350                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2351                 }
2352                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2353                 {
2354                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2355                 }
2356                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2357                 {
2358                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2359                 }
2360
2361                 if (!empty($categories))
2362                 {
2363                         return SimplePie_Misc::array_unique($categories);
2364                 }
2365                 else
2366                 {
2367                         return null;
2368                 }
2369         }
2370
2371         function get_author($key = 0)
2372         {
2373                 $authors = $this->get_authors();
2374                 if (isset($authors[$key]))
2375                 {
2376                         return $authors[$key];
2377                 }
2378                 else
2379                 {
2380                         return null;
2381                 }
2382         }
2383
2384         function get_authors()
2385         {
2386                 $authors = array();
2387                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2388                 {
2389                         $name = null;
2390                         $uri = null;
2391                         $email = null;
2392                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2393                         {
2394                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2395                         }
2396                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2397                         {
2398                                 $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]));
2399                         }
2400                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2401                         {
2402                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2403                         }
2404                         if ($name !== null || $email !== null || $uri !== null)
2405                         {
2406                                 $authors[] =& new $this->author_class($name, $uri, $email);
2407                         }
2408                 }
2409                 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2410                 {
2411                         $name = null;
2412                         $url = null;
2413                         $email = null;
2414                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2415                         {
2416                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2417                         }
2418                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2419                         {
2420                                 $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]));
2421                         }
2422                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2423                         {
2424                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2425                         }
2426                         if ($name !== null || $email !== null || $url !== null)
2427                         {
2428                                 $authors[] =& new $this->author_class($name, $url, $email);
2429                         }
2430                 }
2431                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2432                 {
2433                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2434                 }
2435                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2436                 {
2437                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2438                 }
2439                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2440                 {
2441                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2442                 }
2443
2444                 if (!empty($authors))
2445                 {
2446                         return SimplePie_Misc::array_unique($authors);
2447                 }
2448                 else
2449                 {
2450                         return null;
2451                 }
2452         }
2453
2454         function get_contributor($key = 0)
2455         {
2456                 $contributors = $this->get_contributors();
2457                 if (isset($contributors[$key]))
2458                 {
2459                         return $contributors[$key];
2460                 }
2461                 else
2462                 {
2463                         return null;
2464                 }
2465         }
2466
2467         function get_contributors()
2468         {
2469                 $contributors = array();
2470                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2471                 {
2472                         $name = null;
2473                         $uri = null;
2474                         $email = null;
2475                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2476                         {
2477                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2478                         }
2479                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2480                         {
2481                                 $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]));
2482                         }
2483                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2484                         {
2485                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2486                         }
2487                         if ($name !== null || $email !== null || $uri !== null)
2488                         {
2489                                 $contributors[] =& new $this->author_class($name, $uri, $email);
2490                         }
2491                 }
2492                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2493                 {
2494                         $name = null;
2495                         $url = null;
2496                         $email = null;
2497                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2498                         {
2499                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2500                         }
2501                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2502                         {
2503                                 $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]));
2504                         }
2505                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2506                         {
2507                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2508                         }
2509                         if ($name !== null || $email !== null || $url !== null)
2510                         {
2511                                 $contributors[] =& new $this->author_class($name, $url, $email);
2512                         }
2513                 }
2514
2515                 if (!empty($contributors))
2516                 {
2517                         return SimplePie_Misc::array_unique($contributors);
2518                 }
2519                 else
2520                 {
2521                         return null;
2522                 }
2523         }
2524
2525         function get_link($key = 0, $rel = 'alternate')
2526         {
2527                 $links = $this->get_links($rel);
2528                 if (isset($links[$key]))
2529                 {
2530                         return $links[$key];
2531                 }
2532                 else
2533                 {
2534                         return null;
2535                 }
2536         }
2537
2538         /**
2539          * Added for parity between the parent-level and the item/entry-level.
2540          */
2541         function get_permalink()
2542         {
2543                 return $this->get_link(0);
2544         }
2545
2546         function get_links($rel = 'alternate')
2547         {
2548                 if (!isset($this->data['links']))
2549                 {
2550                         $this->data['links'] = array();
2551                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2552                         {
2553                                 foreach ($links as $link)
2554                                 {
2555                                         if (isset($link['attribs']['']['href']))
2556                                         {
2557                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2558                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2559                                         }
2560                                 }
2561                         }
2562                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2563                         {
2564                                 foreach ($links as $link)
2565                                 {
2566                                         if (isset($link['attribs']['']['href']))
2567                                         {
2568                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2569                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2570
2571                                         }
2572                                 }
2573                         }
2574                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2575                         {
2576                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2577                         }
2578                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2579                         {
2580                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2581                         }
2582                         if ($links = $this->get_channel_tags('', 'link'))
2583                         {
2584                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2585                         }
2586
2587                         $keys = array_keys($this->data['links']);
2588                         foreach ($keys as $key)
2589                         {
2590                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
2591                                 {
2592                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2593                                         {
2594                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2595                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2596                                         }
2597                                         else
2598                                         {
2599                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2600                                         }
2601                                 }
2602                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2603                                 {
2604                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2605                                 }
2606                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2607                         }
2608                 }
2609
2610                 if (isset($this->data['links'][$rel]))
2611                 {
2612                         return $this->data['links'][$rel];
2613                 }
2614                 else
2615                 {
2616                         return null;
2617                 }
2618         }
2619
2620         function get_description()
2621         {
2622                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2623                 {
2624                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2625                 }
2626                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2627                 {
2628                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2629                 }
2630                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2631                 {
2632                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2633                 }
2634                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2635                 {
2636                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2637                 }
2638                 elseif ($return = $this->get_channel_tags('', 'description'))
2639                 {
2640                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2641                 }
2642                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2643                 {
2644                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2645                 }
2646                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2647                 {
2648                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2649                 }
2650                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2651                 {
2652                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2653                 }
2654                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2655                 {
2656                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2657                 }
2658                 else
2659                 {
2660                         return null;
2661                 }
2662         }
2663
2664         function get_copyright()
2665         {
2666                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2667                 {
2668                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2669                 }
2670                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2671                 {
2672                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2673                 }
2674                 elseif ($return = $this->get_channel_tags('', 'copyright'))
2675                 {
2676                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2677                 }
2678                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2679                 {
2680                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2681                 }
2682                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2683                 {
2684                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2685                 }
2686                 else
2687                 {
2688                         return null;
2689                 }
2690         }
2691
2692         function get_language()
2693         {
2694                 if ($return = $this->get_channel_tags('', 'language'))
2695                 {
2696                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697                 }
2698                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2699                 {
2700                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2701                 }
2702                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2703                 {
2704                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2705                 }
2706                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2707                 {
2708                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2709                 }
2710                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2711                 {
2712                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2713                 }
2714                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2715                 {
2716                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2717                 }
2718                 elseif (isset($this->data['headers']['content-language']))
2719                 {
2720                         return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2721                 }
2722                 else
2723                 {
2724                         return null;
2725                 }
2726         }
2727
2728         function get_latitude()
2729         {
2730                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2731                 {
2732                         return (float) $return[0]['data'];
2733                 }
2734                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2735                 {
2736                         return (float) $match[1];
2737                 }
2738                 else
2739                 {
2740                         return null;
2741                 }
2742         }
2743
2744         function get_longitude()
2745         {
2746                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2747                 {
2748                         return (float) $return[0]['data'];
2749                 }
2750                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2751                 {
2752                         return (float) $return[0]['data'];
2753                 }
2754                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2755                 {
2756                         return (float) $match[2];
2757                 }
2758                 else
2759                 {
2760                         return null;
2761                 }
2762         }
2763
2764         function get_image_title()
2765         {
2766                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2767                 {
2768                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2769                 }
2770                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2771                 {
2772                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2773                 }
2774                 elseif ($return = $this->get_image_tags('', 'title'))
2775                 {
2776                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2777                 }
2778                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2779                 {
2780                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781                 }
2782                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2783                 {
2784                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785                 }
2786                 else
2787                 {
2788                         return null;
2789                 }
2790         }
2791
2792         function get_image_url()
2793         {
2794                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2795                 {
2796                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2797                 }
2798                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2799                 {
2800                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2801                 }
2802                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2803                 {
2804                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2805                 }
2806                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2807                 {
2808                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2809                 }
2810                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2811                 {
2812                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813                 }
2814                 elseif ($return = $this->get_image_tags('', 'url'))
2815                 {
2816                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817                 }
2818                 else
2819                 {
2820                         return null;
2821                 }
2822         }
2823
2824         function get_image_link()
2825         {
2826                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2827                 {
2828                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829                 }
2830                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2831                 {
2832                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2833                 }
2834                 elseif ($return = $this->get_image_tags('', 'link'))
2835                 {
2836                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2837                 }
2838                 else
2839                 {
2840                         return null;
2841                 }
2842         }
2843
2844         function get_image_width()
2845         {
2846                 if ($return = $this->get_image_tags('', 'width'))
2847                 {
2848                         return round($return[0]['data']);
2849                 }
2850                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2851                 {
2852                         return 88.0;
2853                 }
2854                 else
2855                 {
2856                         return null;
2857                 }
2858         }
2859
2860         function get_image_height()
2861         {
2862                 if ($return = $this->get_image_tags('', 'height'))
2863                 {
2864                         return round($return[0]['data']);
2865                 }
2866                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2867                 {
2868                         return 31.0;
2869                 }
2870                 else
2871                 {
2872                         return null;
2873                 }
2874         }
2875
2876         function get_item_quantity($max = 0)
2877         {
2878                 $qty = count($this->get_items());
2879                 if ($max == 0)
2880                 {
2881                         return $qty;
2882                 }
2883                 else
2884                 {
2885                         return ($qty > $max) ? $max : $qty;
2886                 }
2887         }
2888
2889         function get_item($key = 0)
2890         {
2891                 $items = $this->get_items();
2892                 if (isset($items[$key]))
2893                 {
2894                         return $items[$key];
2895                 }
2896                 else
2897                 {
2898                         return null;
2899                 }
2900         }
2901
2902         function get_items($start = 0, $end = 0)
2903         {
2904                 if (!empty($this->multifeed_objects))
2905                 {
2906                         return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2907                 }
2908                 elseif (!isset($this->data['items']))
2909                 {
2910                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2911                         {
2912                                 $keys = array_keys($items);
2913                                 foreach ($keys as $key)
2914                                 {
2915                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2916                                 }
2917                         }
2918                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2919                         {
2920                                 $keys = array_keys($items);
2921                                 foreach ($keys as $key)
2922                                 {
2923                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2924                                 }
2925                         }
2926                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2927                         {
2928                                 $keys = array_keys($items);
2929                                 foreach ($keys as $key)
2930                                 {
2931                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2932                                 }
2933                         }
2934                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2935                         {
2936                                 $keys = array_keys($items);
2937                                 foreach ($keys as $key)
2938                                 {
2939                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2940                                 }
2941                         }
2942                         if ($items = $this->get_channel_tags('', 'item'))
2943                         {
2944                                 $keys = array_keys($items);
2945                                 foreach ($keys as $key)
2946                                 {
2947                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2948                                 }
2949                         }
2950                 }
2951
2952                 if (!empty($this->data['items']))
2953                 {
2954                         // If we want to order it by date, check if all items have a date, and then sort it
2955                         if ($this->order_by_date)
2956                         {
2957                                 if (!isset($this->data['ordered_items']))
2958                                 {
2959                                         $do_sort = true;
2960                                         foreach ($this->data['items'] as $item)
2961                                         {
2962                                                 if (!$item->get_date('U'))
2963                                                 {
2964                                                         $do_sort = false;
2965                                                         break;
2966                                                 }
2967                                         }
2968                                         $item = null;
2969                                         $this->data['ordered_items'] = $this->data['items'];
2970                                         if ($do_sort)
2971                                         {
2972                                                 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2973                                         }
2974                                 }
2975                                 $items = $this->data['ordered_items'];
2976                         }
2977                         else
2978                         {
2979                                 $items = $this->data['items'];
2980                         }
2981
2982                         // Slice the data as desired
2983                         if ($end == 0)
2984                         {
2985                                 return array_slice($items, $start);
2986                         }
2987                         else
2988                         {
2989                                 return array_slice($items, $start, $end);
2990                         }
2991                 }
2992                 else
2993                 {
2994                         return array();
2995                 }
2996         }
2997
2998         function sort_items($a, $b)
2999         {
3000                 return $a->get_date('U') <= $b->get_date('U');
3001         }
3002
3003         function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3004         {
3005                 if (is_array($urls) && sizeof($urls) > 0)
3006                 {
3007                         $items = array();
3008                         foreach ($urls as $arg)
3009                         {
3010                                 if (is_a($arg, 'SimplePie'))
3011                                 {
3012                                         $items = array_merge($items, $arg->get_items(0, $limit));
3013                                 }
3014                                 else
3015                                 {
3016                                         trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3017                                 }
3018                         }
3019
3020                         $do_sort = true;
3021                         foreach ($items as $item)
3022                         {
3023                                 if (!$item->get_date('U'))
3024                                 {
3025                                         $do_sort = false;
3026                                         break;
3027                                 }
3028                         }
3029                         $item = null;
3030                         if ($do_sort)
3031                         {
3032                                 usort($items, array('SimplePie', 'sort_items'));
3033                         }
3034
3035                         if ($end == 0)
3036                         {
3037                                 return array_slice($items, $start);
3038                         }
3039                         else
3040                         {
3041                                 return array_slice($items, $start, $end);
3042                         }
3043                 }
3044                 else
3045                 {
3046                         trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3047                         return array();
3048                 }
3049         }
3050 }
3051
3052 class SimplePie_Item
3053 {
3054         var $feed;
3055         var $data = array();
3056
3057         function SimplePie_Item($feed, $data)
3058         {
3059                 $this->feed = $feed;
3060                 $this->data = $data;
3061         }
3062
3063         function __toString()
3064         {
3065                 return md5(serialize($this->data));
3066         }
3067         
3068         /**
3069          * Remove items that link back to this before destroying this object
3070          */
3071         function __destruct()
3072         {
3073                 unset($this->feed);
3074         }
3075
3076         function get_item_tags($namespace, $tag)
3077         {
3078                 if (isset($this->data['child'][$namespace][$tag]))
3079                 {
3080                         return $this->data['child'][$namespace][$tag];
3081                 }
3082                 else
3083                 {
3084                         return null;
3085                 }
3086         }
3087
3088         function get_base($element = array())
3089         {
3090                 return $this->feed->get_base($element);
3091         }
3092
3093         function sanitize($data, $type, $base = '')
3094         {
3095                 return $this->feed->sanitize($data, $type, $base);
3096         }
3097
3098         function get_feed()
3099         {
3100                 return $this->feed;
3101         }
3102
3103         function get_id($hash = false)
3104         {
3105                 if (!$hash)
3106                 {
3107                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3108                         {
3109                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3110                         }
3111                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3112                         {
3113                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3114                         }
3115                         elseif ($return = $this->get_item_tags('', 'guid'))
3116                         {
3117                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3118                         }
3119                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3120                         {
3121                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122                         }
3123                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3124                         {
3125                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126                         }
3127                         elseif (($return = $this->get_permalink()) !== null)
3128                         {
3129                                 return $return;
3130                         }
3131                         elseif (($return = $this->get_title()) !== null)
3132                         {
3133                                 return $return;
3134                         }
3135                 }
3136                 if ($this->get_permalink() !== null || $this->get_title() !== null)
3137                 {
3138                         return md5($this->get_permalink() . $this->get_title());
3139                 }
3140                 else
3141                 {
3142                         return md5(serialize($this->data));
3143                 }
3144         }
3145
3146         function get_title()
3147         {
3148                 if (!isset($this->data['title']))
3149                 {
3150                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3151                         {
3152                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3153                         }
3154                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3155                         {
3156                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3157                         }
3158                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3159                         {
3160                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3161                         }
3162                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3163                         {
3164                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3165                         }
3166                         elseif ($return = $this->get_item_tags('', 'title'))
3167                         {
3168                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3169                         }
3170                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3171                         {
3172                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3173                         }
3174                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3175                         {
3176                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3177                         }
3178                         else
3179                         {
3180                                 $this->data['title'] = null;
3181                         }
3182                 }
3183                 return $this->data['title'];
3184         }
3185
3186         function get_description($description_only = false)
3187         {
3188                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3189                 {
3190                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3191                 }
3192                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3193                 {
3194                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3195                 }
3196                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3197                 {
3198                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3199                 }
3200                 elseif ($return = $this->get_item_tags('', 'description'))
3201                 {
3202                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3203                 }
3204                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3205                 {
3206                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3207                 }
3208                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3209                 {
3210                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3211                 }
3212                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
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_ITUNES, 'subtitle'))
3217                 {
3218                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219                 }
3220                 elseif (!$description_only)
3221                 {
3222                         return $this->get_content(true);
3223                 }
3224                 else
3225                 {
3226                         return null;
3227                 }
3228         }
3229
3230         function get_content($content_only = false)
3231         {
3232                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3233                 {
3234                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3235                 }
3236                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3237                 {
3238                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3239                 }
3240                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3241                 {
3242                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3243                 }
3244                 elseif (!$content_only)
3245                 {
3246                         return $this->get_description(true);
3247                 }
3248                 else
3249                 {
3250                         return null;
3251                 }
3252         }
3253
3254         function get_category($key = 0)
3255         {
3256                 $categories = $this->get_categories();
3257                 if (isset($categories[$key]))
3258                 {
3259                         return $categories[$key];
3260                 }
3261                 else
3262                 {
3263                         return null;
3264                 }
3265         }
3266
3267         function get_categories()
3268         {
3269                 $categories = array();
3270
3271                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3272                 {
3273                         $term = null;
3274                         $scheme = null;
3275                         $label = null;
3276                         if (isset($category['attribs']['']['term']))
3277                         {
3278                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3279                         }
3280                         if (isset($category['attribs']['']['scheme']))
3281                         {
3282                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3283                         }
3284                         if (isset($category['attribs']['']['label']))
3285                         {
3286                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3287                         }
3288                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3289                 }
3290                 foreach ((array) $this->get_item_tags('', 'category') as $category)
3291                 {
3292                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3293                 }
3294                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3295                 {
3296                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3297                 }
3298                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3299                 {
3300                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3301                 }
3302
3303                 if (!empty($categories))
3304                 {
3305                         return SimplePie_Misc::array_unique($categories);
3306                 }
3307                 else
3308                 {
3309                         return null;
3310                 }
3311         }
3312
3313         function get_author($key = 0)
3314         {
3315                 $authors = $this->get_authors();
3316                 if (isset($authors[$key]))
3317                 {
3318                         return $authors[$key];
3319                 }
3320                 else
3321                 {
3322                         return null;
3323                 }
3324         }
3325
3326         function get_contributor($key = 0)
3327         {
3328                 $contributors = $this->get_contributors();
3329                 if (isset($contributors[$key]))
3330                 {
3331                         return $contributors[$key];
3332                 }
3333                 else
3334                 {
3335                         return null;
3336                 }
3337         }
3338
3339         function get_contributors()
3340         {
3341                 $contributors = array();
3342                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3343                 {
3344                         $name = null;
3345                         $uri = null;
3346                         $email = null;
3347                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3348                         {
3349                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3350                         }
3351                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3352                         {
3353                                 $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]));
3354                         }
3355                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3356                         {
3357                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3358                         }
3359                         if ($name !== null || $email !== null || $uri !== null)
3360                         {
3361                                 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3362                         }
3363                 }
3364                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3365                 {
3366                         $name = null;
3367                         $url = null;
3368                         $email = null;
3369                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3370                         {
3371                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3372                         }
3373                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3374                         {
3375                                 $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]));
3376                         }
3377                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3378                         {
3379                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3380                         }
3381                         if ($name !== null || $email !== null || $url !== null)
3382                         {
3383                                 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3384                         }
3385                 }
3386
3387                 if (!empty($contributors))
3388                 {
3389                         return SimplePie_Misc::array_unique($contributors);
3390                 }
3391                 else
3392                 {
3393                         return null;
3394                 }
3395         }
3396
3397         /**
3398          * @todo Atom inheritance (item author, source author, feed author)
3399          */
3400         function get_authors()
3401         {
3402                 $authors = array();
3403                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3404                 {
3405                         $name = null;
3406                         $uri = null;
3407                         $email = null;
3408                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3409                         {
3410                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3411                         }
3412                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3413                         {
3414                                 $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]));
3415                         }
3416                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3417                         {
3418                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3419                         }
3420                         if ($name !== null || $email !== null || $uri !== null)
3421                         {
3422                                 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3423                         }
3424                 }
3425                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3426                 {
3427                         $name = null;
3428                         $url = null;
3429                         $email = null;
3430                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3431                         {
3432                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3433                         }
3434                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3435                         {
3436                                 $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]));
3437                         }
3438                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3439                         {
3440                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3441                         }
3442                         if ($name !== null || $email !== null || $url !== null)
3443                         {
3444                                 $authors[] =& new $this->feed->author_class($name, $url, $email);
3445                         }
3446                 }
3447                 if ($author = $this->get_item_tags('', 'author'))
3448                 {
3449                         $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3450                 }
3451                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3452                 {
3453                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3454                 }
3455                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3456                 {
3457                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3458                 }
3459                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3460                 {
3461                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3462                 }
3463
3464                 if (!empty($authors))
3465                 {
3466                         return SimplePie_Misc::array_unique($authors);
3467                 }
3468                 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3469                 {
3470                         return $authors;
3471                 }
3472                 elseif ($authors = $this->feed->get_authors())
3473                 {
3474                         return $authors;
3475                 }
3476                 else
3477                 {
3478                         return null;
3479                 }
3480         }
3481
3482         function get_copyright()
3483         {
3484                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3485                 {
3486                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3487                 }
3488                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3489                 {
3490                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3491                 }
3492                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3493                 {
3494                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3495                 }
3496                 else
3497                 {
3498                         return null;
3499                 }
3500         }
3501
3502         function get_date($date_format = 'j F Y, g:i a')
3503         {
3504                 if (!isset($this->data['date']))
3505                 {
3506                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3507                         {
3508                                 $this->data['date']['raw'] = $return[0]['data'];
3509                         }
3510                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3511                         {
3512                                 $this->data['date']['raw'] = $return[0]['data'];
3513                         }
3514                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3515                         {
3516                                 $this->data['date']['raw'] = $return[0]['data'];
3517                         }
3518                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3519                         {
3520                                 $this->data['date']['raw'] = $return[0]['data'];
3521                         }
3522                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3523                         {
3524                                 $this->data['date']['raw'] = $return[0]['data'];
3525                         }
3526                         elseif ($return = $this->get_item_tags('', 'pubDate'))
3527                         {
3528                                 $this->data['date']['raw'] = $return[0]['data'];
3529                         }
3530                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3531                         {
3532                                 $this->data['date']['raw'] = $return[0]['data'];
3533                         }
3534                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3535                         {
3536                                 $this->data['date']['raw'] = $return[0]['data'];
3537                         }
3538
3539                         if (!empty($this->data['date']['raw']))
3540                         {
3541                                 $parser = SimplePie_Parse_Date::get();
3542                                 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3543                         }
3544                         else
3545                         {
3546                                 $this->data['date'] = null;
3547                         }
3548                 }
3549                 if ($this->data['date'])
3550                 {
3551                         $date_format = (string) $date_format;
3552                         switch ($date_format)
3553                         {
3554                                 case '':
3555                                         return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3556
3557                                 case 'U':
3558                                         return $this->data['date']['parsed'];
3559
3560                                 default:
3561                                         return date($date_format, $this->data['date']['parsed']);
3562                         }
3563                 }
3564                 else
3565                 {
3566                         return null;
3567                 }
3568         }
3569
3570         function get_local_date($date_format = '%c')
3571         {
3572                 if (!$date_format)
3573                 {
3574                         return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3575                 }
3576                 elseif (($date = $this->get_date('U')) !== null)
3577                 {
3578                         return strftime($date_format, $date);
3579                 }
3580                 else
3581                 {
3582                         return null;
3583                 }
3584         }
3585
3586         function get_permalink()
3587         {
3588                 $link = $this->get_link();
3589                 $enclosure = $this->get_enclosure(0);
3590                 if ($link !== null)
3591                 {
3592                         return $link;
3593                 }
3594                 elseif ($enclosure !== null)
3595                 {
3596                         return $enclosure->get_link();
3597                 }
3598                 else
3599                 {
3600                         return null;
3601                 }
3602         }
3603
3604         function get_link($key = 0, $rel = 'alternate')
3605         {
3606                 $links = $this->get_links($rel);
3607                 if ($links[$key] !== null)
3608                 {
3609                         return $links[$key];
3610                 }
3611                 else
3612                 {
3613                         return null;
3614                 }
3615         }
3616
3617         function get_links($rel = 'alternate')
3618         {
3619                 if (!isset($this->data['links']))
3620                 {
3621                         $this->data['links'] = array();
3622                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3623                         {
3624                                 if (isset($link['attribs']['']['href']))
3625                                 {
3626                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3627                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3628
3629                                 }
3630                         }
3631                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3632                         {
3633                                 if (isset($link['attribs']['']['href']))
3634                                 {
3635                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3636                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3637                                 }
3638                         }
3639                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3640                         {
3641                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3642                         }
3643                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3644                         {
3645                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3646                         }
3647                         if ($links = $this->get_item_tags('', 'link'))
3648                         {
3649                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3650                         }
3651                         if ($links = $this->get_item_tags('', 'guid'))
3652                         {
3653                                 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3654                                 {
3655                                         $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3656                                 }
3657                         }
3658
3659                         $keys = array_keys($this->data['links']);
3660                         foreach ($keys as $key)
3661                         {
3662                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
3663                                 {
3664                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3665                                         {
3666                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3667                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3668                                         }
3669                                         else
3670                                         {
3671                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3672                                         }
3673                                 }
3674                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3675                                 {
3676                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3677                                 }
3678                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3679                         }
3680                 }
3681                 if (isset($this->data['links'][$rel]))
3682                 {
3683                         return $this->data['links'][$rel];
3684                 }
3685                 else
3686                 {
3687                         return null;
3688                 }
3689         }
3690
3691         /**
3692          * @todo Add ability to prefer one type of content over another (in a media group).
3693          */
3694         function get_enclosure($key = 0, $prefer = null)
3695         {
3696                 $enclosures = $this->get_enclosures();
3697                 if (isset($enclosures[$key]))
3698                 {
3699                         return $enclosures[$key];
3700                 }
3701                 else
3702                 {
3703                         return null;
3704                 }
3705         }
3706
3707         /**
3708          * Grabs all available enclosures (podcasts, etc.)
3709          *
3710          * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3711          *
3712          * 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.
3713          *
3714          * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3715          * @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).
3716          */
3717         function get_enclosures()
3718         {
3719                 if (!isset($this->data['enclosures']))
3720                 {
3721                         $this->data['enclosures'] = array();
3722
3723                         // Elements
3724                         $captions_parent = null;
3725                         $categories_parent = null;
3726                         $copyrights_parent = null;
3727                         $credits_parent = null;
3728                         $description_parent = null;
3729                         $duration_parent = null;
3730                         $hashes_parent = null;
3731                         $keywords_parent = null;
3732                         $player_parent = null;
3733                         $ratings_parent = null;
3734                         $restrictions_parent = null;
3735                         $thumbnails_parent = null;
3736                         $title_parent = null;
3737
3738                         // Let's do the channel and item-level ones first, and just re-use them if we need to.
3739                         $parent = $this->get_feed();
3740
3741                         // CAPTIONS
3742                         if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3743                         {
3744                                 foreach ($captions as $caption)
3745                                 {
3746                                         $caption_type = null;
3747                                         $caption_lang = null;
3748                                         $caption_startTime = null;
3749                                         $caption_endTime = null;
3750                                         $caption_text = null;
3751                                         if (isset($caption['attribs']['']['type']))
3752                                         {
3753                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3754                                         }
3755                                         if (isset($caption['attribs']['']['lang']))
3756                                         {
3757                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3758                                         }
3759                                         if (isset($caption['attribs']['']['start']))
3760                                         {
3761                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3762                                         }
3763                                         if (isset($caption['attribs']['']['end']))
3764                                         {
3765                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3766                                         }
3767                                         if (isset($caption['data']))
3768                                         {
3769                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3770                                         }
3771                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3772                                 }
3773                         }
3774                         elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3775                         {
3776                                 foreach ($captions as $caption)
3777                                 {
3778                                         $caption_type = null;
3779                                         $caption_lang = null;
3780                                         $caption_startTime = null;
3781                                         $caption_endTime = null;
3782                                         $caption_text = null;
3783                                         if (isset($caption['attribs']['']['type']))
3784                                         {
3785                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3786                                         }
3787                                         if (isset($caption['attribs']['']['lang']))
3788                                         {
3789                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3790                                         }
3791                                         if (isset($caption['attribs']['']['start']))
3792                                         {
3793                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3794                                         }
3795                                         if (isset($caption['attribs']['']['end']))
3796                                         {
3797                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3798                                         }
3799                                         if (isset($caption['data']))
3800                                         {
3801                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3802                                         }
3803                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3804                                 }
3805                         }
3806                         if (is_array($captions_parent))
3807                         {
3808                                 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3809                         }
3810
3811                         // CATEGORIES
3812                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3813                         {
3814                                 $term = null;
3815                                 $scheme = null;
3816                                 $label = null;
3817                                 if (isset($category['data']))
3818                                 {
3819                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3820                                 }
3821                                 if (isset($category['attribs']['']['scheme']))
3822                                 {
3823                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3824                                 }
3825                                 else
3826                                 {
3827                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3828                                 }
3829                                 if (isset($category['attribs']['']['label']))
3830                                 {
3831                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3832                                 }
3833                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3834                         }
3835                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3836                         {
3837                                 $term = null;
3838                                 $scheme = null;
3839                                 $label = null;
3840                                 if (isset($category['data']))
3841                                 {
3842                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3843                                 }
3844                                 if (isset($category['attribs']['']['scheme']))
3845                                 {
3846                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3847                                 }
3848                                 else
3849                                 {
3850                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3851                                 }
3852                                 if (isset($category['attribs']['']['label']))
3853                                 {
3854                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3855                                 }
3856                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3857                         }
3858                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3859                         {
3860                                 $term = null;
3861                                 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3862                                 $label = null;
3863                                 if (isset($category['attribs']['']['text']))
3864                                 {
3865                                         $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3866                                 }
3867                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3868
3869                                 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3870                                 {
3871                                         foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3872                                         {
3873                                                 if (isset($subcategory['attribs']['']['text']))
3874                                                 {
3875                                                         $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3876                                                 }
3877                                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3878                                         }
3879                                 }
3880                         }
3881                         if (is_array($categories_parent))
3882                         {
3883                                 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3884                         }
3885
3886                         // COPYRIGHT
3887                         if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3888                         {
3889                                 $copyright_url = null;
3890                                 $copyright_label = null;
3891                                 if (isset($copyright[0]['attribs']['']['url']))
3892                                 {
3893                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3894                                 }
3895                                 if (isset($copyright[0]['data']))
3896                                 {
3897                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3898                                 }
3899                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3900                         }
3901                         elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3902                         {
3903                                 $copyright_url = null;
3904                                 $copyright_label = null;
3905                                 if (isset($copyright[0]['attribs']['']['url']))
3906                                 {
3907                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3908                                 }
3909                                 if (isset($copyright[0]['data']))
3910                                 {
3911                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3912                                 }
3913                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3914                         }
3915
3916                         // CREDITS
3917                         if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3918                         {
3919                                 foreach ($credits as $credit)
3920                                 {
3921                                         $credit_role = null;
3922                                         $credit_scheme = null;
3923                                         $credit_name = null;
3924                                         if (isset($credit['attribs']['']['role']))
3925                                         {
3926                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3927                                         }
3928                                         if (isset($credit['attribs']['']['scheme']))
3929                                         {
3930                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3931                                         }
3932                                         else
3933                                         {
3934                                                 $credit_scheme = 'urn:ebu';
3935                                         }
3936                                         if (isset($credit['data']))
3937                                         {
3938                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3939                                         }
3940                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3941                                 }
3942                         }
3943                         elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3944                         {
3945                                 foreach ($credits as $credit)
3946                                 {
3947                                         $credit_role = null;
3948                                         $credit_scheme = null;
3949                                         $credit_name = null;
3950                                         if (isset($credit['attribs']['']['role']))
3951                                         {
3952                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3953                                         }
3954                                         if (isset($credit['attribs']['']['scheme']))
3955                                         {
3956                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3957                                         }
3958                                         else
3959                                         {
3960                                                 $credit_scheme = 'urn:ebu';
3961                                         }
3962                                         if (isset($credit['data']))
3963                                         {
3964                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3965                                         }
3966                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3967                                 }
3968                         }
3969                         if (is_array($credits_parent))
3970                         {
3971                                 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3972                         }
3973
3974                         // DESCRIPTION
3975                         if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3976                         {
3977                                 if (isset($description_parent[0]['data']))
3978                                 {
3979                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3980                                 }
3981                         }
3982                         elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3983                         {
3984                                 if (isset($description_parent[0]['data']))
3985                                 {
3986                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3987                                 }
3988                         }
3989
3990                         // DURATION
3991                         if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3992                         {
3993                                 $seconds = null;
3994                                 $minutes = null;
3995                                 $hours = null;
3996                                 if (isset($duration_parent[0]['data']))
3997                                 {
3998                                         $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3999                                         if (sizeof($temp) > 0)
4000                                         {
4001                                                 (int) $seconds = array_pop($temp);
4002                                         }
4003                                         if (sizeof($temp) > 0)
4004                                         {
4005                                                 (int) $minutes = array_pop($temp);
4006                                                 $seconds += $minutes * 60;
4007                                         }
4008                                         if (sizeof($temp) > 0)
4009                                         {
4010                                                 (int) $hours = array_pop($temp);
4011                                                 $seconds += $hours * 3600;
4012                                         }
4013                                         unset($temp);
4014                                         $duration_parent = $seconds;
4015                                 }
4016                         }
4017
4018                         // HASHES
4019                         if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4020                         {
4021                                 foreach ($hashes_iterator as $hash)
4022                                 {
4023                                         $value = null;
4024                                         $algo = null;
4025                                         if (isset($hash['data']))
4026                                         {
4027                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4028                                         }
4029                                         if (isset($hash['attribs']['']['algo']))
4030                                         {
4031                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4032                                         }
4033                                         else
4034                                         {
4035                                                 $algo = 'md5';
4036                                         }
4037                                         $hashes_parent[] = $algo.':'.$value;
4038                                 }
4039                         }
4040                         elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4041                         {
4042                                 foreach ($hashes_iterator as $hash)
4043                                 {
4044                                         $value = null;
4045                                         $algo = null;
4046                                         if (isset($hash['data']))
4047                                         {
4048                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4049                                         }
4050                                         if (isset($hash['attribs']['']['algo']))
4051                                         {
4052                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4053                                         }
4054                                         else
4055                                         {
4056                                                 $algo = 'md5';
4057                                         }
4058                                         $hashes_parent[] = $algo.':'.$value;
4059                                 }
4060                         }
4061                         if (is_array($hashes_parent))
4062                         {
4063                                 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4064                         }
4065
4066                         // KEYWORDS
4067                         if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4068                         {
4069                                 if (isset($keywords[0]['data']))
4070                                 {
4071                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4072                                         foreach ($temp as $word)
4073                                         {
4074                                                 $keywords_parent[] = trim($word);
4075                                         }
4076                                 }
4077                                 unset($temp);
4078                         }
4079                         elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, '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 = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, '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_ITUNES, '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                         if (is_array($keywords_parent))
4116                         {
4117                                 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4118                         }
4119
4120                         // PLAYER
4121                         if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4122                         {
4123                                 if (isset($player_parent[0]['attribs']['']['url']))
4124                                 {
4125                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4126                                 }
4127                         }
4128                         elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4129                         {
4130                                 if (isset($player_parent[0]['attribs']['']['url']))
4131                                 {
4132                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4133                                 }
4134                         }
4135
4136                         // RATINGS
4137                         if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4138                         {
4139                                 foreach ($ratings as $rating)
4140                                 {
4141                                         $rating_scheme = null;
4142                                         $rating_value = null;
4143                                         if (isset($rating['attribs']['']['scheme']))
4144                                         {
4145                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4146                                         }
4147                                         else
4148                                         {
4149                                                 $rating_scheme = 'urn:simple';
4150                                         }
4151                                         if (isset($rating['data']))
4152                                         {
4153                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4154                                         }
4155                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4156                                 }
4157                         }
4158                         elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4159                         {
4160                                 foreach ($ratings as $rating)
4161                                 {
4162                                         $rating_scheme = 'urn:itunes';
4163                                         $rating_value = null;
4164                                         if (isset($rating['data']))
4165                                         {
4166                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4167                                         }
4168                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4169                                 }
4170                         }
4171                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4172                         {
4173                                 foreach ($ratings as $rating)
4174                                 {
4175                                         $rating_scheme = null;
4176                                         $rating_value = null;
4177                                         if (isset($rating['attribs']['']['scheme']))
4178                                         {
4179                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4180                                         }
4181                                         else
4182                                         {
4183                                                 $rating_scheme = 'urn:simple';
4184                                         }
4185                                         if (isset($rating['data']))
4186                                         {
4187                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4188                                         }
4189                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4190                                 }
4191                         }
4192                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4193                         {
4194                                 foreach ($ratings as $rating)
4195                                 {
4196                                         $rating_scheme = 'urn:itunes';
4197                                         $rating_value = null;
4198                                         if (isset($rating['data']))
4199                                         {
4200                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4201                                         }
4202                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4203                                 }
4204                         }
4205                         if (is_array($ratings_parent))
4206                         {
4207                                 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4208                         }
4209
4210                         // RESTRICTIONS
4211                         if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4212                         {
4213                                 foreach ($restrictions as $restriction)
4214                                 {
4215                                         $restriction_relationship = null;
4216                                         $restriction_type = null;
4217                                         $restriction_value = null;
4218                                         if (isset($restriction['attribs']['']['relationship']))
4219                                         {
4220                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4221                                         }
4222                                         if (isset($restriction['attribs']['']['type']))
4223                                         {
4224                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4225                                         }
4226                                         if (isset($restriction['data']))
4227                                         {
4228                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4229                                         }
4230                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4231                                 }
4232                         }
4233                         elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4234                         {
4235                                 foreach ($restrictions as $restriction)
4236                                 {
4237                                         $restriction_relationship = 'allow';
4238                                         $restriction_type = null;
4239                                         $restriction_value = 'itunes';
4240                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4241                                         {
4242                                                 $restriction_relationship = 'deny';
4243                                         }
4244                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4245                                 }
4246                         }
4247                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4248                         {
4249                                 foreach ($restrictions as $restriction)
4250                                 {
4251                                         $restriction_relationship = null;
4252                                         $restriction_type = null;
4253                                         $restriction_value = null;
4254                                         if (isset($restriction['attribs']['']['relationship']))
4255                                         {
4256                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4257                                         }
4258                                         if (isset($restriction['attribs']['']['type']))
4259                                         {
4260                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4261                                         }
4262                                         if (isset($restriction['data']))
4263                                         {
4264                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4265                                         }
4266                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4267                                 }
4268                         }
4269                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4270                         {
4271                                 foreach ($restrictions as $restriction)
4272                                 {
4273                                         $restriction_relationship = 'allow';
4274                                         $restriction_type = null;
4275                                         $restriction_value = 'itunes';
4276                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4277                                         {
4278                                                 $restriction_relationship = 'deny';
4279                                         }
4280                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4281                                 }
4282                         }
4283                         if (is_array($restrictions_parent))
4284                         {
4285                                 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4286                         }
4287
4288                         // THUMBNAILS
4289                         if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4290                         {
4291                                 foreach ($thumbnails as $thumbnail)
4292                                 {
4293                                         if (isset($thumbnail['attribs']['']['url']))
4294                                         {
4295                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4296                                         }
4297                                 }
4298                         }
4299                         elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4300                         {
4301                                 foreach ($thumbnails as $thumbnail)
4302                                 {
4303                                         if (isset($thumbnail['attribs']['']['url']))
4304                                         {
4305                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4306                                         }
4307                                 }
4308                         }
4309
4310                         // TITLES
4311                         if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4312                         {
4313                                 if (isset($title_parent[0]['data']))
4314                                 {
4315                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4316                                 }
4317                         }
4318                         elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4319                         {
4320                                 if (isset($title_parent[0]['data']))
4321                                 {
4322                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4323                                 }
4324                         }
4325
4326                         // Clear the memory
4327                         unset($parent);
4328
4329                         // If we have media:group tags, loop through them.
4330                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4331                         {
4332                                 // If we have media:content tags, loop through them.
4333                                 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4334                                 {
4335                                         if (isset($content['attribs']['']['url']))
4336                                         {
4337                                                 // Attributes
4338                                                 $bitrate = null;
4339                                                 $channels = null;
4340                                                 $duration = null;
4341                                                 $expression = null;
4342                                                 $framerate = null;
4343                                                 $height = null;
4344                                                 $javascript = null;
4345                                                 $lang = null;
4346                                                 $length = null;
4347                                                 $medium = null;
4348                                                 $samplingrate = null;
4349                                                 $type = null;
4350                                                 $url = null;
4351                                                 $width = null;
4352
4353                                                 // Elements
4354                                                 $captions = null;
4355                                                 $categories = null;
4356                                                 $copyrights = null;
4357                                                 $credits = null;
4358                                                 $description = null;
4359                                                 $hashes = null;
4360                                                 $keywords = null;
4361                                                 $player = null;
4362                                                 $ratings = null;
4363                                                 $restrictions = null;
4364                                                 $thumbnails = null;
4365                                                 $title = null;
4366
4367                                                 // Start checking the attributes of media:content
4368                                                 if (isset($content['attribs']['']['bitrate']))
4369                                                 {
4370                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4371                                                 }
4372                                                 if (isset($content['attribs']['']['channels']))
4373                                                 {
4374                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4375                                                 }
4376                                                 if (isset($content['attribs']['']['duration']))
4377                                                 {
4378                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4379                                                 }
4380                                                 else
4381                                                 {
4382                                                         $duration = $duration_parent;
4383                                                 }
4384                                                 if (isset($content['attribs']['']['expression']))
4385                                                 {
4386                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4387                                                 }
4388                                                 if (isset($content['attribs']['']['framerate']))
4389                                                 {
4390                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4391                                                 }
4392                                                 if (isset($content['attribs']['']['height']))
4393                                                 {
4394                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4395                                                 }
4396                                                 if (isset($content['attribs']['']['lang']))
4397                                                 {
4398                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4399                                                 }
4400                                                 if (isset($content['attribs']['']['fileSize']))
4401                                                 {
4402                                                         $length = ceil($content['attribs']['']['fileSize']);
4403                                                 }
4404                                                 if (isset($content['attribs']['']['medium']))
4405                                                 {
4406                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4407                                                 }
4408                                                 if (isset($content['attribs']['']['samplingrate']))
4409                                                 {
4410                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4411                                                 }
4412                                                 if (isset($content['attribs']['']['type']))
4413                                                 {
4414                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4415                                                 }
4416                                                 if (isset($content['attribs']['']['width']))
4417                                                 {
4418                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4419                                                 }
4420                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4421
4422                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4423
4424                                                 // CAPTIONS
4425                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4426                                                 {
4427                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4428                                                         {
4429                                                                 $caption_type = null;
4430                                                                 $caption_lang = null;
4431                                                                 $caption_startTime = null;
4432                                                                 $caption_endTime = null;
4433                                                                 $caption_text = null;
4434                                                                 if (isset($caption['attribs']['']['type']))
4435                                                                 {
4436                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4437                                                                 }
4438                                                                 if (isset($caption['attribs']['']['lang']))
4439                                                                 {
4440                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4441                                                                 }
4442                                                                 if (isset($caption['attribs']['']['start']))
4443                                                                 {
4444                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4445                                                                 }
4446                                                                 if (isset($caption['attribs']['']['end']))
4447                                                                 {
4448                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4449                                                                 }
4450                                                                 if (isset($caption['data']))
4451                                                                 {
4452                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4453                                                                 }
4454                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4455                                                         }
4456                                                         if (is_array($captions))
4457                                                         {
4458                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4459                                                         }
4460                                                 }
4461                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4462                                                 {
4463                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4464                                                         {
4465                                                                 $caption_type = null;
4466                                                                 $caption_lang = null;
4467                                                                 $caption_startTime = null;
4468                                                                 $caption_endTime = null;
4469                                                                 $caption_text = null;
4470                                                                 if (isset($caption['attribs']['']['type']))
4471                                                                 {
4472                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4473                                                                 }
4474                                                                 if (isset($caption['attribs']['']['lang']))
4475                                                                 {
4476                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4477                                                                 }
4478                                                                 if (isset($caption['attribs']['']['start']))
4479                                                                 {
4480                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4481                                                                 }
4482                                                                 if (isset($caption['attribs']['']['end']))
4483                                                                 {
4484                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4485                                                                 }
4486                                                                 if (isset($caption['data']))
4487                                                                 {
4488                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4489                                                                 }
4490                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4491                                                         }
4492                                                         if (is_array($captions))
4493                                                         {
4494                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4495                                                         }
4496                                                 }
4497                                                 else
4498                                                 {
4499                                                         $captions = $captions_parent;
4500                                                 }
4501
4502                                                 // CATEGORIES
4503                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4504                                                 {
4505                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4506                                                         {
4507                                                                 $term = null;
4508                                                                 $scheme = null;
4509                                                                 $label = null;
4510                                                                 if (isset($category['data']))
4511                                                                 {
4512                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4513                                                                 }
4514                                                                 if (isset($category['attribs']['']['scheme']))
4515                                                                 {
4516                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4517                                                                 }
4518                                                                 else
4519                                                                 {
4520                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4521                                                                 }
4522                                                                 if (isset($category['attribs']['']['label']))
4523                                                                 {
4524                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4525                                                                 }
4526                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4527                                                         }
4528                                                 }
4529                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4530                                                 {
4531                                                         foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4532                                                         {
4533                                                                 $term = null;
4534                                                                 $scheme = null;
4535                                                                 $label = null;
4536                                                                 if (isset($category['data']))
4537                                                                 {
4538                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4539                                                                 }
4540                                                                 if (isset($category['attribs']['']['scheme']))
4541                                                                 {
4542                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4543                                                                 }
4544                                                                 else
4545                                                                 {
4546                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4547                                                                 }
4548                                                                 if (isset($category['attribs']['']['label']))
4549                                                                 {
4550                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4551                                                                 }
4552                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4553                                                         }
4554                                                 }
4555                                                 if (is_array($categories) && is_array($categories_parent))
4556                                                 {
4557                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4558                                                 }
4559                                                 elseif (is_array($categories))
4560                                                 {
4561                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
4562                                                 }
4563                                                 elseif (is_array($categories_parent))
4564                                                 {
4565                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4566                                                 }
4567
4568                                                 // COPYRIGHTS
4569                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4570                                                 {
4571                                                         $copyright_url = null;
4572                                                         $copyright_label = null;
4573                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4574                                                         {
4575                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4576                                                         }
4577                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4578                                                         {
4579                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4580                                                         }
4581                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4582                                                 }
4583                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4584                                                 {
4585                                                         $copyright_url = null;
4586                                                         $copyright_label = null;
4587                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4588                                                         {
4589                                                                 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4590                                                         }
4591                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4592                                                         {
4593                                                                 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4594                                                         }
4595                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4596                                                 }
4597                                                 else
4598                                                 {
4599                                                         $copyrights = $copyrights_parent;
4600                                                 }
4601
4602                                                 // CREDITS
4603                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4604                                                 {
4605                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4606                                                         {
4607                                                                 $credit_role = null;
4608                                                                 $credit_scheme = null;
4609                                                                 $credit_name = null;
4610                                                                 if (isset($credit['attribs']['']['role']))
4611                                                                 {
4612                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4613                                                                 }
4614                                                                 if (isset($credit['attribs']['']['scheme']))
4615                                                                 {
4616                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4617                                                                 }
4618                                                                 else
4619                                                                 {
4620                                                                         $credit_scheme = 'urn:ebu';
4621                                                                 }
4622                                                                 if (isset($credit['data']))
4623                                                                 {
4624                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4625                                                                 }
4626                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4627                                                         }
4628                                                         if (is_array($credits))
4629                                                         {
4630                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4631                                                         }
4632                                                 }
4633                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4634                                                 {
4635                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4636                                                         {
4637                                                                 $credit_role = null;
4638                                                                 $credit_scheme = null;
4639                                                                 $credit_name = null;
4640                                                                 if (isset($credit['attribs']['']['role']))
4641                                                                 {
4642                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4643                                                                 }
4644                                                                 if (isset($credit['attribs']['']['scheme']))
4645                                                                 {
4646                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4647                                                                 }
4648                                                                 else
4649                                                                 {
4650                                                                         $credit_scheme = 'urn:ebu';
4651                                                                 }
4652                                                                 if (isset($credit['data']))
4653                                                                 {
4654                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4655                                                                 }
4656                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4657                                                         }
4658                                                         if (is_array($credits))
4659                                                         {
4660                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4661                                                         }
4662                                                 }
4663                                                 else
4664                                                 {
4665                                                         $credits = $credits_parent;
4666                                                 }
4667
4668                                                 // DESCRIPTION
4669                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4670                                                 {
4671                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4672                                                 }
4673                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4674                                                 {
4675                                                         $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4676                                                 }
4677                                                 else
4678                                                 {
4679                                                         $description = $description_parent;
4680                                                 }
4681
4682                                                 // HASHES
4683                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4684                                                 {
4685                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4686                                                         {
4687                                                                 $value = null;
4688                                                                 $algo = null;
4689                                                                 if (isset($hash['data']))
4690                                                                 {
4691                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4692                                                                 }
4693                                                                 if (isset($hash['attribs']['']['algo']))
4694                                                                 {
4695                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4696                                                                 }
4697                                                                 else
4698                                                                 {
4699                                                                         $algo = 'md5';
4700                                                                 }
4701                                                                 $hashes[] = $algo.':'.$value;
4702                                                         }
4703                                                         if (is_array($hashes))
4704                                                         {
4705                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4706                                                         }
4707                                                 }
4708                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4709                                                 {
4710                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4711                                                         {
4712                                                                 $value = null;
4713                                                                 $algo = null;
4714                                                                 if (isset($hash['data']))
4715                                                                 {
4716                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4717                                                                 }
4718                                                                 if (isset($hash['attribs']['']['algo']))
4719                                                                 {
4720                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4721                                                                 }
4722                                                                 else
4723                                                                 {
4724                                                                         $algo = 'md5';
4725                                                                 }
4726                                                                 $hashes[] = $algo.':'.$value;
4727                                                         }
4728                                                         if (is_array($hashes))
4729                                                         {
4730                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4731                                                         }
4732                                                 }
4733                                                 else
4734                                                 {
4735                                                         $hashes = $hashes_parent;
4736                                                 }
4737
4738                                                 // KEYWORDS
4739                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4740                                                 {
4741                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4742                                                         {
4743                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4744                                                                 foreach ($temp as $word)
4745                                                                 {
4746                                                                         $keywords[] = trim($word);
4747                                                                 }
4748                                                                 unset($temp);
4749                                                         }
4750                                                         if (is_array($keywords))
4751                                                         {
4752                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4753                                                         }
4754                                                 }
4755                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4756                                                 {
4757                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4758                                                         {
4759                                                                 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4760                                                                 foreach ($temp as $word)
4761                                                                 {
4762                                                                         $keywords[] = trim($word);
4763                                                                 }
4764                                                                 unset($temp);
4765                                                         }
4766                                                         if (is_array($keywords))
4767                                                         {
4768                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4769                                                         }
4770                                                 }
4771                                                 else
4772                                                 {
4773                                                         $keywords = $keywords_parent;
4774                                                 }
4775
4776                                                 // PLAYER
4777                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4778                                                 {
4779                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4780                                                 }
4781                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4782                                                 {
4783                                                         $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4784                                                 }
4785                                                 else
4786                                                 {
4787                                                         $player = $player_parent;
4788                                                 }
4789
4790                                                 // RATINGS
4791                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4792                                                 {
4793                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4794                                                         {
4795                                                                 $rating_scheme = null;
4796                                                                 $rating_value = null;
4797                                                                 if (isset($rating['attribs']['']['scheme']))
4798                                                                 {
4799                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4800                                                                 }
4801                                                                 else
4802                                                                 {
4803                                                                         $rating_scheme = 'urn:simple';
4804                                                                 }
4805                                                                 if (isset($rating['data']))
4806                                                                 {
4807                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4808                                                                 }
4809                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4810                                                         }
4811                                                         if (is_array($ratings))
4812                                                         {
4813                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4814                                                         }
4815                                                 }
4816                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4817                                                 {
4818                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4819                                                         {
4820                                                                 $rating_scheme = null;
4821                                                                 $rating_value = null;
4822                                                                 if (isset($rating['attribs']['']['scheme']))
4823                                                                 {
4824                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4825                                                                 }
4826                                                                 else
4827                                                                 {
4828                                                                         $rating_scheme = 'urn:simple';
4829                                                                 }
4830                                                                 if (isset($rating['data']))
4831                                                                 {
4832                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4833                                                                 }
4834                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4835                                                         }
4836                                                         if (is_array($ratings))
4837                                                         {
4838                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4839                                                         }
4840                                                 }
4841                                                 else
4842                                                 {
4843                                                         $ratings = $ratings_parent;
4844                                                 }
4845
4846                                                 // RESTRICTIONS
4847                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4848                                                 {
4849                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4850                                                         {
4851                                                                 $restriction_relationship = null;
4852                                                                 $restriction_type = null;
4853                                                                 $restriction_value = null;
4854                                                                 if (isset($restriction['attribs']['']['relationship']))
4855                                                                 {
4856                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4857                                                                 }
4858                                                                 if (isset($restriction['attribs']['']['type']))
4859                                                                 {
4860                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4861                                                                 }
4862                                                                 if (isset($restriction['data']))
4863                                                                 {
4864                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4865                                                                 }
4866                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4867                                                         }
4868                                                         if (is_array($restrictions))
4869                                                         {
4870                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4871                                                         }
4872                                                 }
4873                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4874                                                 {
4875                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4876                                                         {
4877                                                                 $restriction_relationship = null;
4878                                                                 $restriction_type = null;
4879                                                                 $restriction_value = null;
4880                                                                 if (isset($restriction['attribs']['']['relationship']))
4881                                                                 {
4882                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4883                                                                 }
4884                                                                 if (isset($restriction['attribs']['']['type']))
4885                                                                 {
4886                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4887                                                                 }
4888                                                                 if (isset($restriction['data']))
4889                                                                 {
4890                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4891                                                                 }
4892                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4893                                                         }
4894                                                         if (is_array($restrictions))
4895                                                         {
4896                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4897                                                         }
4898                                                 }
4899                                                 else
4900                                                 {
4901                                                         $restrictions = $restrictions_parent;
4902                                                 }
4903
4904                                                 // THUMBNAILS
4905                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4906                                                 {
4907                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4908                                                         {
4909                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4910                                                         }
4911                                                         if (is_array($thumbnails))
4912                                                         {
4913                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4914                                                         }
4915                                                 }
4916                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4917                                                 {
4918                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4919                                                         {
4920                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4921                                                         }
4922                                                         if (is_array($thumbnails))
4923                                                         {
4924                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4925                                                         }
4926                                                 }
4927                                                 else
4928                                                 {
4929                                                         $thumbnails = $thumbnails_parent;
4930                                                 }
4931
4932                                                 // TITLES
4933                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4934                                                 {
4935                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4936                                                 }
4937                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4938                                                 {
4939                                                         $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4940                                                 }
4941                                                 else
4942                                                 {
4943                                                         $title = $title_parent;
4944                                                 }
4945
4946                                                 $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);
4947                                         }
4948                                 }
4949                         }
4950
4951                         // If we have standalone media:content tags, loop through them.
4952                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4953                         {
4954                                 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4955                                 {
4956                                         if (isset($content['attribs']['']['url']))
4957                                         {
4958                                                 // Attributes
4959                                                 $bitrate = null;
4960                                                 $channels = null;
4961                                                 $duration = null;
4962                                                 $expression = null;
4963                                                 $framerate = null;
4964                                                 $height = null;
4965                                                 $javascript = null;
4966                                                 $lang = null;
4967                                                 $length = null;
4968                                                 $medium = null;
4969                                                 $samplingrate = null;
4970                                                 $type = null;
4971                                                 $url = null;
4972                                                 $width = null;
4973
4974                                                 // Elements
4975                                                 $captions = null;
4976                                                 $categories = null;
4977                                                 $copyrights = null;
4978                                                 $credits = null;
4979                                                 $description = null;
4980                                                 $hashes = null;
4981                                                 $keywords = null;
4982                                                 $player = null;
4983                                                 $ratings = null;
4984                                                 $restrictions = null;
4985                                                 $thumbnails = null;
4986                                                 $title = null;
4987
4988                                                 // Start checking the attributes of media:content
4989                                                 if (isset($content['attribs']['']['bitrate']))
4990                                                 {
4991                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4992                                                 }
4993                                                 if (isset($content['attribs']['']['channels']))
4994                                                 {
4995                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4996                                                 }
4997                                                 if (isset($content['attribs']['']['duration']))
4998                                                 {
4999                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5000                                                 }
5001                                                 else
5002                                                 {
5003                                                         $duration = $duration_parent;
5004                                                 }
5005                                                 if (isset($content['attribs']['']['expression']))
5006                                                 {
5007                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5008                                                 }
5009                                                 if (isset($content['attribs']['']['framerate']))
5010                                                 {
5011                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5012                                                 }
5013                                                 if (isset($content['attribs']['']['height']))
5014                                                 {
5015                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5016                                                 }
5017                                                 if (isset($content['attribs']['']['lang']))
5018                                                 {
5019                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5020                                                 }
5021                                                 if (isset($content['attribs']['']['fileSize']))
5022                                                 {
5023                                                         $length = ceil($content['attribs']['']['fileSize']);
5024                                                 }
5025                                                 if (isset($content['attribs']['']['medium']))
5026                                                 {
5027                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5028                                                 }
5029                                                 if (isset($content['attribs']['']['samplingrate']))
5030                                                 {
5031                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5032                                                 }
5033                                                 if (isset($content['attribs']['']['type']))
5034                                                 {
5035                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5036                                                 }
5037                                                 if (isset($content['attribs']['']['width']))
5038                                                 {
5039                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5040                                                 }
5041                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5042
5043                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5044
5045                                                 // CAPTIONS
5046                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5047                                                 {
5048                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5049                                                         {
5050                                                                 $caption_type = null;
5051                                                                 $caption_lang = null;
5052                                                                 $caption_startTime = null;
5053                                                                 $caption_endTime = null;
5054                                                                 $caption_text = null;
5055                                                                 if (isset($caption['attribs']['']['type']))
5056                                                                 {
5057                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5058                                                                 }
5059                                                                 if (isset($caption['attribs']['']['lang']))
5060                                                                 {
5061                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5062                                                                 }
5063                                                                 if (isset($caption['attribs']['']['start']))
5064                                                                 {
5065                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5066                                                                 }
5067                                                                 if (isset($caption['attribs']['']['end']))
5068                                                                 {
5069                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5070                                                                 }
5071                                                                 if (isset($caption['data']))
5072                                                                 {
5073                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5074                                                                 }
5075                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5076                                                         }
5077                                                         if (is_array($captions))
5078                                                         {
5079                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
5080                                                         }
5081                                                 }
5082                                                 else
5083                                                 {
5084                                                         $captions = $captions_parent;
5085                                                 }
5086
5087                                                 // CATEGORIES
5088                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5089                                                 {
5090                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5091                                                         {
5092                                                                 $term = null;
5093                                                                 $scheme = null;
5094                                                                 $label = null;
5095                                                                 if (isset($category['data']))
5096                                                                 {
5097                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5098                                                                 }
5099                                                                 if (isset($category['attribs']['']['scheme']))
5100                                                                 {
5101                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5102                                                                 }
5103                                                                 else
5104                                                                 {
5105                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
5106                                                                 }
5107                                                                 if (isset($category['attribs']['']['label']))
5108                                                                 {
5109                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5110                                                                 }
5111                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5112                                                         }
5113                                                 }
5114                                                 if (is_array($categories) && is_array($categories_parent))
5115                                                 {
5116                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5117                                                 }
5118                                                 elseif (is_array($categories))
5119                                                 {
5120                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
5121                                                 }
5122                                                 elseif (is_array($categories_parent))
5123                                                 {
5124                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5125                                                 }
5126                                                 else
5127                                                 {
5128                                                         $categories = null;
5129                                                 }
5130
5131                                                 // COPYRIGHTS
5132                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5133                                                 {
5134                                                         $copyright_url = null;
5135                                                         $copyright_label = null;
5136                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5137                                                         {
5138                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5139                                                         }
5140                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5141                                                         {
5142                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5143                                                         }
5144                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5145                                                 }
5146                                                 else
5147                                                 {
5148                                                         $copyrights = $copyrights_parent;
5149                                                 }
5150
5151                                                 // CREDITS
5152                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5153                                                 {
5154                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5155                                                         {
5156                                                                 $credit_role = null;
5157                                                                 $credit_scheme = null;
5158                                                                 $credit_name = null;
5159                                                                 if (isset($credit['attribs']['']['role']))
5160                                                                 {
5161                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5162                                                                 }
5163                                                                 if (isset($credit['attribs']['']['scheme']))
5164                                                                 {
5165                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5166                                                                 }
5167                                                                 else
5168                                                                 {
5169                                                                         $credit_scheme = 'urn:ebu';
5170                                                                 }
5171                                                                 if (isset($credit['data']))
5172                                                                 {
5173                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5174                                                                 }
5175                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5176                                                         }
5177                                                         if (is_array($credits))
5178                                                         {
5179                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
5180                                                         }
5181                                                 }
5182                                                 else
5183                                                 {
5184                                                         $credits = $credits_parent;
5185                                                 }
5186
5187                                                 // DESCRIPTION
5188                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5189                                                 {
5190                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5191                                                 }
5192                                                 else
5193                                                 {
5194                                                         $description = $description_parent;
5195                                                 }
5196
5197                                                 // HASHES
5198                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5199                                                 {
5200                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5201                                                         {
5202                                                                 $value = null;
5203                                                                 $algo = null;
5204                                                                 if (isset($hash['data']))
5205                                                                 {
5206                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5207                                                                 }
5208                                                                 if (isset($hash['attribs']['']['algo']))
5209                                                                 {
5210                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5211                                                                 }
5212                                                                 else
5213                                                                 {
5214                                                                         $algo = 'md5';
5215                                                                 }
5216                                                                 $hashes[] = $algo.':'.$value;
5217                                                         }
5218                                                         if (is_array($hashes))
5219                                                         {
5220                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5221                                                         }
5222                                                 }
5223                                                 else
5224                                                 {
5225                                                         $hashes = $hashes_parent;
5226                                                 }
5227
5228                                                 // KEYWORDS
5229                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5230                                                 {
5231                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5232                                                         {
5233                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5234                                                                 foreach ($temp as $word)
5235                                                                 {
5236                                                                         $keywords[] = trim($word);
5237                                                                 }
5238                                                                 unset($temp);
5239                                                         }
5240                                                         if (is_array($keywords))
5241                                                         {
5242                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5243                                                         }
5244                                                 }
5245                                                 else
5246                                                 {
5247                                                         $keywords = $keywords_parent;
5248                                                 }
5249
5250                                                 // PLAYER
5251                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5252                                                 {
5253                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5254                                                 }
5255                                                 else
5256                                                 {
5257                                                         $player = $player_parent;
5258                                                 }
5259
5260                                                 // RATINGS
5261                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5262                                                 {
5263                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5264                                                         {
5265                                                                 $rating_scheme = null;
5266                                                                 $rating_value = null;
5267                                                                 if (isset($rating['attribs']['']['scheme']))
5268                                                                 {
5269                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5270                                                                 }
5271                                                                 else
5272                                                                 {
5273                                                                         $rating_scheme = 'urn:simple';
5274                                                                 }
5275                                                                 if (isset($rating['data']))
5276                                                                 {
5277                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5278                                                                 }
5279                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5280                                                         }
5281                                                         if (is_array($ratings))
5282                                                         {
5283                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5284                                                         }
5285                                                 }
5286                                                 else
5287                                                 {
5288                                                         $ratings = $ratings_parent;
5289                                                 }
5290
5291                                                 // RESTRICTIONS
5292                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5293                                                 {
5294                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5295                                                         {
5296                                                                 $restriction_relationship = null;
5297                                                                 $restriction_type = null;
5298                                                                 $restriction_value = null;
5299                                                                 if (isset($restriction['attribs']['']['relationship']))
5300                                                                 {
5301                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5302                                                                 }
5303                                                                 if (isset($restriction['attribs']['']['type']))
5304                                                                 {
5305                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5306                                                                 }
5307                                                                 if (isset($restriction['data']))
5308                                                                 {
5309                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5310                                                                 }
5311                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5312                                                         }
5313                                                         if (is_array($restrictions))
5314                                                         {
5315                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5316                                                         }
5317                                                 }
5318                                                 else
5319                                                 {
5320                                                         $restrictions = $restrictions_parent;
5321                                                 }
5322
5323                                                 // THUMBNAILS
5324                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5325                                                 {
5326                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5327                                                         {
5328                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5329                                                         }
5330                                                         if (is_array($thumbnails))
5331                                                         {
5332                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5333                                                         }
5334                                                 }
5335                                                 else
5336                                                 {
5337                                                         $thumbnails = $thumbnails_parent;
5338                                                 }
5339
5340                                                 // TITLES
5341                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5342                                                 {
5343                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5344                                                 }
5345                                                 else
5346                                                 {
5347                                                         $title = $title_parent;
5348                                                 }
5349
5350                                                 $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);
5351                                         }
5352                                 }
5353                         }
5354
5355                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5356                         {
5357                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5358                                 {
5359                                         // Attributes
5360                                         $bitrate = null;
5361                                         $channels = null;
5362                                         $duration = null;
5363                                         $expression = null;
5364                                         $framerate = null;
5365                                         $height = null;
5366                                         $javascript = null;
5367                                         $lang = null;
5368                                         $length = null;
5369                                         $medium = null;
5370                                         $samplingrate = null;
5371                                         $type = null;
5372                                         $url = null;
5373                                         $width = null;
5374
5375                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5376                                         if (isset($link['attribs']['']['type']))
5377                                         {
5378                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5379                                         }
5380                                         if (isset($link['attribs']['']['length']))
5381                                         {
5382                                                 $length = ceil($link['attribs']['']['length']);
5383                                         }
5384
5385                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5386                                         $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);
5387                                 }
5388                         }
5389
5390                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5391                         {
5392                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5393                                 {
5394                                         // Attributes
5395                                         $bitrate = null;
5396                                         $channels = null;
5397                                         $duration = null;
5398                                         $expression = null;
5399                                         $framerate = null;
5400                                         $height = null;
5401                                         $javascript = null;
5402                                         $lang = null;
5403                                         $length = null;
5404                                         $medium = null;
5405                                         $samplingrate = null;
5406                                         $type = null;
5407                                         $url = null;
5408                                         $width = null;
5409
5410                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5411                                         if (isset($link['attribs']['']['type']))
5412                                         {
5413                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5414                                         }
5415                                         if (isset($link['attribs']['']['length']))
5416                                         {
5417                                                 $length = ceil($link['attribs']['']['length']);
5418                                         }
5419
5420                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5421                                         $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);
5422                                 }
5423                         }
5424
5425                         if ($enclosure = $this->get_item_tags('', 'enclosure'))
5426                         {
5427                                 if (isset($enclosure[0]['attribs']['']['url']))
5428                                 {
5429                                         // Attributes
5430                                         $bitrate = null;
5431                                         $channels = null;
5432                                         $duration = null;
5433                                         $expression = null;
5434                                         $framerate = null;
5435                                         $height = null;
5436                                         $javascript = null;
5437                                         $lang = null;
5438                                         $length = null;
5439                                         $medium = null;
5440                                         $samplingrate = null;
5441                                         $type = null;
5442                                         $url = null;
5443                                         $width = null;
5444
5445                                         $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5446                                         if (isset($enclosure[0]['attribs']['']['type']))
5447                                         {
5448                                                 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5449                                         }
5450                                         if (isset($enclosure[0]['attribs']['']['length']))
5451                                         {
5452                                                 $length = ceil($enclosure[0]['attribs']['']['length']);
5453                                         }
5454
5455                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5456                                         $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);
5457                                 }
5458                         }
5459
5460                         if (sizeof($this->data['enclosures']) == 0)
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                         $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5467                 }
5468                 if (!empty($this->data['enclosures']))
5469                 {
5470                         return $this->data['enclosures'];
5471                 }
5472                 else
5473                 {
5474                         return null;
5475                 }
5476         }
5477
5478         function get_latitude()
5479         {
5480                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5481                 {
5482                         return (float) $return[0]['data'];
5483                 }
5484                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5485                 {
5486                         return (float) $match[1];
5487                 }
5488                 else
5489                 {
5490                         return null;
5491                 }
5492         }
5493
5494         function get_longitude()
5495         {
5496                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5497                 {
5498                         return (float) $return[0]['data'];
5499                 }
5500                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5501                 {
5502                         return (float) $return[0]['data'];
5503                 }
5504                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5505                 {
5506                         return (float) $match[2];
5507                 }
5508                 else
5509                 {
5510                         return null;
5511                 }
5512         }
5513         
5514         function get_source()
5515         {
5516                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5517                 {
5518                         return new $this->feed->source_class($this, $return[0]);
5519                 }
5520                 else
5521                 {
5522                         return null;
5523                 }
5524         }
5525
5526         /**
5527          * Creates the add_to_* methods' return data
5528          *
5529          * @access private
5530          * @param string $item_url String to prefix to the item permalink
5531          * @param string $title_url String to prefix to the item title
5532          * (and suffix to the item permalink)
5533          * @return mixed URL if feed exists, false otherwise
5534          */
5535         function add_to_service($item_url, $title_url = null)
5536         {
5537                 if ($this->get_permalink() !== null)
5538                 {
5539                         $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5540                         if ($title_url !== null && $this->get_title() !== null)
5541                         {
5542                                 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5543                         }
5544                         return $return;
5545                 }
5546                 else
5547                 {
5548                         return null;
5549                 }
5550         }
5551
5552         function add_to_blinklist()
5553         {
5554                 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5555         }
5556
5557         function add_to_blogmarks()
5558         {
5559                 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5560         }
5561
5562         function add_to_delicious()
5563         {
5564                 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5565         }
5566
5567         function add_to_digg()
5568         {
5569                 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5570         }
5571
5572         function add_to_furl()
5573         {
5574                 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5575         }
5576
5577         function add_to_magnolia()
5578         {
5579                 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5580         }
5581
5582         function add_to_myweb20()
5583         {
5584                 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5585         }
5586
5587         function add_to_newsvine()
5588         {
5589                 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5590         }
5591
5592         function add_to_reddit()
5593         {
5594                 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5595         }
5596
5597         function add_to_segnalo()
5598         {
5599                 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5600         }
5601
5602         function add_to_simpy()
5603         {
5604                 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5605         }
5606
5607         function add_to_spurl()
5608         {
5609                 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5610         }
5611
5612         function add_to_wists()
5613         {
5614                 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5615         }
5616
5617         function search_technorati()
5618         {
5619                 return $this->add_to_service('http://www.technorati.com/search/');
5620         }
5621 }
5622
5623 class SimplePie_Source
5624 {
5625         var $item;
5626         var $data = array();
5627
5628         function SimplePie_Source($item, $data)
5629         {
5630                 $this->item = $item;
5631                 $this->data = $data;
5632         }
5633
5634         function __toString()
5635         {
5636                 return md5(serialize($this->data));
5637         }
5638         
5639         /**
5640          * Remove items that link back to this before destroying this object
5641          */
5642         function __destruct()
5643         {
5644                 unset($this->item);
5645         }
5646
5647         function get_source_tags($namespace, $tag)
5648         {
5649                 if (isset($this->data['child'][$namespace][$tag]))
5650                 {
5651                         return $this->data['child'][$namespace][$tag];
5652                 }
5653                 else
5654                 {
5655                         return null;
5656                 }
5657         }
5658
5659         function get_base($element = array())
5660         {
5661                 return $this->item->get_base($element);
5662         }
5663
5664         function sanitize($data, $type, $base = '')
5665         {
5666                 return $this->item->sanitize($data, $type, $base);
5667         }
5668
5669         function get_item()
5670         {
5671                 return $this->item;
5672         }
5673
5674         function get_title()
5675         {
5676                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5677                 {
5678                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5679                 }
5680                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5681                 {
5682                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5683                 }
5684                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5685                 {
5686                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5687                 }
5688                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5689                 {
5690                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5691                 }
5692                 elseif ($return = $this->get_source_tags('', 'title'))
5693                 {
5694                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5695                 }
5696                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5697                 {
5698                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5699                 }
5700                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5701                 {
5702                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5703                 }
5704                 else
5705                 {
5706                         return null;
5707                 }
5708         }
5709
5710         function get_category($key = 0)
5711         {
5712                 $categories = $this->get_categories();
5713                 if (isset($categories[$key]))
5714                 {
5715                         return $categories[$key];
5716                 }
5717                 else
5718                 {
5719                         return null;
5720                 }
5721         }
5722
5723         function get_categories()
5724         {
5725                 $categories = array();
5726
5727                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5728                 {
5729                         $term = null;
5730                         $scheme = null;
5731                         $label = null;
5732                         if (isset($category['attribs']['']['term']))
5733                         {
5734                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5735                         }
5736                         if (isset($category['attribs']['']['scheme']))
5737                         {
5738                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5739                         }
5740                         if (isset($category['attribs']['']['label']))
5741                         {
5742                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5743                         }
5744                         $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5745                 }
5746                 foreach ((array) $this->get_source_tags('', 'category') as $category)
5747                 {
5748                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5749                 }
5750                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5751                 {
5752                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5753                 }
5754                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5755                 {
5756                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5757                 }
5758
5759                 if (!empty($categories))
5760                 {
5761                         return SimplePie_Misc::array_unique($categories);
5762                 }
5763                 else
5764                 {
5765                         return null;
5766                 }
5767         }
5768
5769         function get_author($key = 0)
5770         {
5771                 $authors = $this->get_authors();
5772                 if (isset($authors[$key]))
5773                 {
5774                         return $authors[$key];
5775                 }
5776                 else
5777                 {
5778                         return null;
5779                 }
5780         }
5781
5782         function get_authors()
5783         {
5784                 $authors = array();
5785                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5786                 {
5787                         $name = null;
5788                         $uri = null;
5789                         $email = null;
5790                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5791                         {
5792                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5793                         }
5794                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5795                         {
5796                                 $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]));
5797                         }
5798                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5799                         {
5800                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5801                         }
5802                         if ($name !== null || $email !== null || $uri !== null)
5803                         {
5804                                 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5805                         }
5806                 }
5807                 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5808                 {
5809                         $name = null;
5810                         $url = null;
5811                         $email = null;
5812                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5813                         {
5814                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5815                         }
5816                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5817                         {
5818                                 $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]));
5819                         }
5820                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5821                         {
5822                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5823                         }
5824                         if ($name !== null || $email !== null || $url !== null)
5825                         {
5826                                 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5827                         }
5828                 }
5829                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5830                 {
5831                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5832                 }
5833                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5834                 {
5835                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5836                 }
5837                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5838                 {
5839                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5840                 }
5841
5842                 if (!empty($authors))
5843                 {
5844                         return SimplePie_Misc::array_unique($authors);
5845                 }
5846                 else
5847                 {
5848                         return null;
5849                 }
5850         }
5851
5852         function get_contributor($key = 0)
5853         {
5854                 $contributors = $this->get_contributors();
5855                 if (isset($contributors[$key]))
5856                 {
5857                         return $contributors[$key];
5858                 }
5859                 else
5860                 {
5861                         return null;
5862                 }
5863         }
5864
5865         function get_contributors()
5866         {
5867                 $contributors = array();
5868                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5869                 {
5870                         $name = null;
5871                         $uri = null;
5872                         $email = null;
5873                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5874                         {
5875                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5876                         }
5877                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5878                         {
5879                                 $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]));
5880                         }
5881                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5882                         {
5883                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5884                         }
5885                         if ($name !== null || $email !== null || $uri !== null)
5886                         {
5887                                 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5888                         }
5889                 }
5890                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5891                 {
5892                         $name = null;
5893                         $url = null;
5894                         $email = null;
5895                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5896                         {
5897                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5898                         }
5899                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5900                         {
5901                                 $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]));
5902                         }
5903                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5904                         {
5905                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5906                         }
5907                         if ($name !== null || $email !== null || $url !== null)
5908                         {
5909                                 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5910                         }
5911                 }
5912
5913                 if (!empty($contributors))
5914                 {
5915                         return SimplePie_Misc::array_unique($contributors);
5916                 }
5917                 else
5918                 {
5919                         return null;
5920                 }
5921         }
5922
5923         function get_link($key = 0, $rel = 'alternate')
5924         {
5925                 $links = $this->get_links($rel);
5926                 if (isset($links[$key]))
5927                 {
5928                         return $links[$key];
5929                 }
5930                 else
5931                 {
5932                         return null;
5933                 }
5934         }
5935
5936         /**
5937          * Added for parity between the parent-level and the item/entry-level.
5938          */
5939         function get_permalink()
5940         {
5941                 return $this->get_link(0);
5942         }
5943
5944         function get_links($rel = 'alternate')
5945         {
5946                 if (!isset($this->data['links']))
5947                 {
5948                         $this->data['links'] = array();
5949                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5950                         {
5951                                 foreach ($links as $link)
5952                                 {
5953                                         if (isset($link['attribs']['']['href']))
5954                                         {
5955                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5956                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5957                                         }
5958                                 }
5959                         }
5960                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
5961                         {
5962                                 foreach ($links as $link)
5963                                 {
5964                                         if (isset($link['attribs']['']['href']))
5965                                         {
5966                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5967                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5968
5969                                         }
5970                                 }
5971                         }
5972                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
5973                         {
5974                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5975                         }
5976                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
5977                         {
5978                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5979                         }
5980                         if ($links = $this->get_source_tags('', 'link'))
5981                         {
5982                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5983                         }
5984
5985                         $keys = array_keys($this->data['links']);
5986                         foreach ($keys as $key)
5987                         {
5988                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
5989                                 {
5990                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
5991                                         {
5992                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
5993                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
5994                                         }
5995                                         else
5996                                         {
5997                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
5998                                         }
5999                                 }
6000                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6001                                 {
6002                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6003                                 }
6004                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6005                         }
6006                 }
6007
6008                 if (isset($this->data['links'][$rel]))
6009                 {
6010                         return $this->data['links'][$rel];
6011                 }
6012                 else
6013                 {
6014                         return null;
6015                 }
6016         }
6017
6018         function get_description()
6019         {
6020                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6021                 {
6022                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6023                 }
6024                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6025                 {
6026                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6027                 }
6028                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6029                 {
6030                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6031                 }
6032                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6033                 {
6034                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6035                 }
6036                 elseif ($return = $this->get_source_tags('', 'description'))
6037                 {
6038                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6039                 }
6040                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6041                 {
6042                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6043                 }
6044                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6045                 {
6046                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6047                 }
6048                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6049                 {
6050                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6051                 }
6052                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6053                 {
6054                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6055                 }
6056                 else
6057                 {
6058                         return null;
6059                 }
6060         }
6061
6062         function get_copyright()
6063         {
6064                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6065                 {
6066                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6067                 }
6068                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6069                 {
6070                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6071                 }
6072                 elseif ($return = $this->get_source_tags('', 'copyright'))
6073                 {
6074                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6075                 }
6076                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6077                 {
6078                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6079                 }
6080                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6081                 {
6082                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6083                 }
6084                 else
6085                 {
6086                         return null;
6087                 }
6088         }
6089
6090         function get_language()
6091         {
6092                 if ($return = $this->get_source_tags('', 'language'))
6093                 {
6094                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6095                 }
6096                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6097                 {
6098                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6099                 }
6100                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6101                 {
6102                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6103                 }
6104                 elseif (isset($this->data['xml_lang']))
6105                 {
6106                         return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6107                 }
6108                 else
6109                 {
6110                         return null;
6111                 }
6112         }
6113
6114         function get_latitude()
6115         {
6116                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6117                 {
6118                         return (float) $return[0]['data'];
6119                 }
6120                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6121                 {
6122                         return (float) $match[1];
6123                 }
6124                 else
6125                 {
6126                         return null;
6127                 }
6128         }
6129
6130         function get_longitude()
6131         {
6132                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6133                 {
6134                         return (float) $return[0]['data'];
6135                 }
6136                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6137                 {
6138                         return (float) $return[0]['data'];
6139                 }
6140                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6141                 {
6142                         return (float) $match[2];
6143                 }
6144                 else
6145                 {
6146                         return null;
6147                 }
6148         }
6149
6150         function get_image_url()
6151         {
6152                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6153                 {
6154                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6155                 }
6156                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6157                 {
6158                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6159                 }
6160                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6161                 {
6162                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6163                 }
6164                 else
6165                 {
6166                         return null;
6167                 }
6168         }
6169 }
6170
6171 class SimplePie_Author
6172 {
6173         var $name;
6174         var $link;
6175         var $email;
6176
6177         // Constructor, used to input the data
6178         function SimplePie_Author($name = null, $link = null, $email = null)
6179         {
6180                 $this->name = $name;
6181                 $this->link = $link;
6182                 $this->email = $email;
6183         }
6184
6185         function __toString()
6186         {
6187                 // There is no $this->data here
6188                 return md5(serialize($this));
6189         }
6190
6191         function get_name()
6192         {
6193                 if ($this->name !== null)
6194                 {
6195                         return $this->name;
6196                 }
6197                 else
6198                 {
6199                         return null;
6200                 }
6201         }
6202
6203         function get_link()
6204         {
6205                 if ($this->link !== null)
6206                 {
6207                         return $this->link;
6208                 }
6209                 else
6210                 {
6211                         return null;
6212                 }
6213         }
6214
6215         function get_email()
6216         {
6217                 if ($this->email !== null)
6218                 {
6219                         return $this->email;
6220                 }
6221                 else
6222                 {
6223                         return null;
6224                 }
6225         }
6226 }
6227
6228 class SimplePie_Category
6229 {
6230         var $term;
6231         var $scheme;
6232         var $label;
6233
6234         // Constructor, used to input the data
6235         function SimplePie_Category($term = null, $scheme = null, $label = null)
6236         {
6237                 $this->term = $term;
6238                 $this->scheme = $scheme;
6239                 $this->label = $label;
6240         }
6241
6242         function __toString()
6243         {
6244                 // There is no $this->data here
6245                 return md5(serialize($this));
6246         }
6247
6248         function get_term()
6249         {
6250                 if ($this->term !== null)
6251                 {
6252                         return $this->term;
6253                 }
6254                 else
6255                 {
6256                         return null;
6257                 }
6258         }
6259
6260         function get_scheme()
6261         {
6262                 if ($this->scheme !== null)
6263                 {
6264                         return $this->scheme;
6265                 }
6266                 else
6267                 {
6268                         return null;
6269                 }
6270         }
6271
6272         function get_label()
6273         {
6274                 if ($this->label !== null)
6275                 {
6276                         return $this->label;
6277                 }
6278                 else
6279                 {
6280                         return $this->get_term();
6281                 }
6282         }
6283 }
6284
6285 class SimplePie_Enclosure
6286 {
6287         var $bitrate;
6288         var $captions;
6289         var $categories;
6290         var $channels;
6291         var $copyright;
6292         var $credits;
6293         var $description;
6294         var $duration;
6295         var $expression;
6296         var $framerate;
6297         var $handler;
6298         var $hashes;
6299         var $height;
6300         var $javascript;
6301         var $keywords;
6302         var $lang;
6303         var $length;
6304         var $link;
6305         var $medium;
6306         var $player;
6307         var $ratings;
6308         var $restrictions;
6309         var $samplingrate;
6310         var $thumbnails;
6311         var $title;
6312         var $type;
6313         var $width;
6314
6315         // Constructor, used to input the data
6316         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)
6317         {
6318                 $this->bitrate = $bitrate;
6319                 $this->captions = $captions;
6320                 $this->categories = $categories;
6321                 $this->channels = $channels;
6322                 $this->copyright = $copyright;
6323                 $this->credits = $credits;
6324                 $this->description = $description;
6325                 $this->duration = $duration;
6326                 $this->expression = $expression;
6327                 $this->framerate = $framerate;
6328                 $this->hashes = $hashes;
6329                 $this->height = $height;
6330                 $this->javascript = $javascript;
6331                 $this->keywords = $keywords;
6332                 $this->lang = $lang;
6333                 $this->length = $length;
6334                 $this->link = $link;
6335                 $this->medium = $medium;
6336                 $this->player = $player;
6337                 $this->ratings = $ratings;
6338                 $this->restrictions = $restrictions;
6339                 $this->samplingrate = $samplingrate;
6340                 $this->thumbnails = $thumbnails;
6341                 $this->title = $title;
6342                 $this->type = $type;
6343                 $this->width = $width;
6344                 if (class_exists('idna_convert'))
6345                 {
6346                         $idn =& new idna_convert;
6347                         $parsed = SimplePie_Misc::parse_url($link);
6348                         $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6349                 }
6350                 $this->handler = $this->get_handler(); // Needs to load last
6351         }
6352
6353         function __toString()
6354         {
6355                 // There is no $this->data here
6356                 return md5(serialize($this));
6357         }
6358
6359         function get_bitrate()
6360         {
6361                 if ($this->bitrate !== null)
6362                 {
6363                         return $this->bitrate;
6364                 }
6365                 else
6366                 {
6367                         return null;
6368                 }
6369         }
6370
6371         function get_caption($key = 0)
6372         {
6373                 $captions = $this->get_captions();
6374                 if (isset($captions[$key]))
6375                 {
6376                         return $captions[$key];
6377                 }
6378                 else
6379                 {
6380                         return null;
6381                 }
6382         }
6383
6384         function get_captions()
6385         {
6386                 if ($this->captions !== null)
6387                 {
6388                         return $this->captions;
6389                 }
6390                 else
6391                 {
6392                         return null;
6393                 }
6394         }
6395
6396         function get_category($key = 0)
6397         {
6398                 $categories = $this->get_categories();
6399                 if (isset($categories[$key]))
6400                 {
6401                         return $categories[$key];
6402                 }
6403                 else
6404                 {
6405                         return null;
6406                 }
6407         }
6408
6409         function get_categories()
6410         {
6411                 if ($this->categories !== null)
6412                 {
6413                         return $this->categories;
6414                 }
6415                 else
6416                 {
6417                         return null;
6418                 }
6419         }
6420
6421         function get_channels()
6422         {
6423                 if ($this->channels !== null)
6424                 {
6425                         return $this->channels;
6426                 }
6427                 else
6428                 {
6429                         return null;
6430                 }
6431         }
6432
6433         function get_copyright()
6434         {
6435                 if ($this->copyright !== null)
6436                 {
6437                         return $this->copyright;
6438                 }
6439                 else
6440                 {
6441                         return null;
6442                 }
6443         }
6444
6445         function get_credit($key = 0)
6446         {
6447                 $credits = $this->get_credits();
6448                 if (isset($credits[$key]))
6449                 {
6450                         return $credits[$key];
6451                 }
6452                 else
6453                 {
6454                         return null;
6455                 }
6456         }
6457
6458         function get_credits()
6459         {
6460                 if ($this->credits !== null)
6461                 {
6462                         return $this->credits;
6463                 }
6464                 else
6465                 {
6466                         return null;
6467                 }
6468         }
6469
6470         function get_description()
6471         {
6472                 if ($this->description !== null)
6473                 {
6474                         return $this->description;
6475                 }
6476                 else
6477                 {
6478                         return null;
6479                 }
6480         }
6481
6482         function get_duration($convert = false)
6483         {
6484                 if ($this->duration !== null)
6485                 {
6486                         if ($convert)
6487                         {
6488                                 $time = SimplePie_Misc::time_hms($this->duration);
6489                                 return $time;
6490                         }
6491                         else
6492                         {
6493                                 return $this->duration;
6494                         }
6495                 }
6496                 else
6497                 {
6498                         return null;
6499                 }
6500         }
6501
6502         function get_expression()
6503         {
6504                 if ($this->expression !== null)
6505                 {
6506                         return $this->expression;
6507                 }
6508                 else
6509                 {
6510                         return 'full';
6511                 }
6512         }
6513
6514         function get_extension()
6515         {
6516                 if ($this->link !== null)
6517                 {
6518                         $url = SimplePie_Misc::parse_url($this->link);
6519                         if ($url['path'] !== '')
6520                         {
6521                                 return pathinfo($url['path'], PATHINFO_EXTENSION);
6522                         }
6523                 }
6524                 return null;
6525         }
6526
6527         function get_framerate()
6528         {
6529                 if ($this->framerate !== null)
6530                 {
6531                         return $this->framerate;
6532                 }
6533                 else
6534                 {
6535                         return null;
6536                 }
6537         }
6538
6539         function get_handler()
6540         {
6541                 return $this->get_real_type(true);
6542         }
6543
6544         function get_hash($key = 0)
6545         {
6546                 $hashes = $this->get_hashes();
6547                 if (isset($hashes[$key]))
6548                 {
6549                         return $hashes[$key];
6550                 }
6551                 else
6552                 {
6553                         return null;
6554                 }
6555         }
6556
6557         function get_hashes()
6558         {
6559                 if ($this->hashes !== null)
6560                 {
6561                         return $this->hashes;
6562                 }
6563                 else
6564                 {
6565                         return null;
6566                 }
6567         }
6568
6569         function get_height()
6570         {
6571                 if ($this->height !== null)
6572                 {
6573                         return $this->height;
6574                 }
6575                 else
6576                 {
6577                         return null;
6578                 }
6579         }
6580
6581         function get_language()
6582         {
6583                 if ($this->lang !== null)
6584                 {
6585                         return $this->lang;
6586                 }
6587                 else
6588                 {
6589                         return null;
6590                 }
6591         }
6592
6593         function get_keyword($key = 0)
6594         {
6595                 $keywords = $this->get_keywords();
6596                 if (isset($keywords[$key]))
6597                 {
6598                         return $keywords[$key];
6599                 }
6600                 else
6601                 {
6602                         return null;
6603                 }
6604         }
6605
6606         function get_keywords()
6607         {
6608                 if ($this->keywords !== null)
6609                 {
6610                         return $this->keywords;
6611                 }
6612                 else
6613                 {
6614                         return null;
6615                 }
6616         }
6617
6618         function get_length()
6619         {
6620                 if ($this->length !== null)
6621                 {
6622                         return $this->length;
6623                 }
6624                 else
6625                 {
6626                         return null;
6627                 }
6628         }
6629
6630         function get_link()
6631         {
6632                 if ($this->link !== null)
6633                 {
6634                         return urldecode($this->link);
6635                 }
6636                 else
6637                 {
6638                         return null;
6639                 }
6640         }
6641
6642         function get_medium()
6643         {
6644                 if ($this->medium !== null)
6645                 {
6646                         return $this->medium;
6647                 }
6648                 else
6649                 {
6650                         return null;
6651                 }
6652         }
6653
6654         function get_player()
6655         {
6656                 if ($this->player !== null)
6657                 {
6658                         return $this->player;
6659                 }
6660                 else
6661                 {
6662                         return null;
6663                 }
6664         }
6665
6666         function get_rating($key = 0)
6667         {
6668                 $ratings = $this->get_ratings();
6669                 if (isset($ratings[$key]))
6670                 {
6671                         return $ratings[$key];
6672                 }
6673                 else
6674                 {
6675                         return null;
6676                 }
6677         }
6678
6679         function get_ratings()
6680         {
6681                 if ($this->ratings !== null)
6682                 {
6683                         return $this->ratings;
6684                 }
6685                 else
6686                 {
6687                         return null;
6688                 }
6689         }
6690
6691         function get_restriction($key = 0)
6692         {
6693                 $restrictions = $this->get_restrictions();
6694                 if (isset($restrictions[$key]))
6695                 {
6696                         return $restrictions[$key];
6697                 }
6698                 else
6699                 {
6700                         return null;
6701                 }
6702         }
6703
6704         function get_restrictions()
6705         {
6706                 if ($this->restrictions !== null)
6707                 {
6708                         return $this->restrictions;
6709                 }
6710                 else
6711                 {
6712                         return null;
6713                 }
6714         }
6715
6716         function get_sampling_rate()
6717         {
6718                 if ($this->samplingrate !== null)
6719                 {
6720                         return $this->samplingrate;
6721                 }
6722                 else
6723                 {
6724                         return null;
6725                 }
6726         }
6727
6728         function get_size()
6729         {
6730                 $length = $this->get_length();
6731                 if ($length !== null)
6732                 {
6733                         return round($length/1048576, 2);
6734                 }
6735                 else
6736                 {
6737                         return null;
6738                 }
6739         }
6740
6741         function get_thumbnail($key = 0)
6742         {
6743                 $thumbnails = $this->get_thumbnails();
6744                 if (isset($thumbnails[$key]))
6745                 {
6746                         return $thumbnails[$key];
6747                 }
6748                 else
6749                 {
6750                         return null;
6751                 }
6752         }
6753
6754         function get_thumbnails()
6755         {
6756                 if ($this->thumbnails !== null)
6757                 {
6758                         return $this->thumbnails;
6759                 }
6760                 else
6761                 {
6762                         return null;
6763                 }
6764         }
6765
6766         function get_title()
6767         {
6768                 if ($this->title !== null)
6769                 {
6770                         return $this->title;
6771                 }
6772                 else
6773                 {
6774                         return null;
6775                 }
6776         }
6777
6778         function get_type()
6779         {
6780                 if ($this->type !== null)
6781                 {
6782                         return $this->type;
6783                 }
6784                 else
6785                 {
6786                         return null;
6787                 }
6788         }
6789
6790         function get_width()
6791         {
6792                 if ($this->width !== null)
6793                 {
6794                         return $this->width;
6795                 }
6796                 else
6797                 {
6798                         return null;
6799                 }
6800         }
6801
6802         function native_embed($options='')
6803         {
6804                 return $this->embed($options, true);
6805         }
6806
6807         /**
6808          * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6809          */
6810         function embed($options = '', $native = false)
6811         {
6812                 // Set up defaults
6813                 $audio = '';
6814                 $video = '';
6815                 $alt = '';
6816                 $altclass = '';
6817                 $loop = 'false';
6818                 $width = 'auto';
6819                 $height = 'auto';
6820                 $bgcolor = '#ffffff';
6821                 $mediaplayer = '';
6822                 $widescreen = false;
6823                 $handler = $this->get_handler();
6824                 $type = $this->get_real_type();
6825
6826                 // Process options and reassign values as necessary
6827                 if (is_array($options))
6828                 {
6829                         extract($options);
6830                 }
6831                 else
6832                 {
6833                         $options = explode(',', $options);
6834                         foreach($options as $option)
6835                         {
6836                                 $opt = explode(':', $option, 2);
6837                                 if (isset($opt[0], $opt[1]))
6838                                 {
6839                                         $opt[0] = trim($opt[0]);
6840                                         $opt[1] = trim($opt[1]);
6841                                         switch ($opt[0])
6842                                         {
6843                                                 case 'audio':
6844                                                         $audio = $opt[1];
6845                                                         break;
6846
6847                                                 case 'video':
6848                                                         $video = $opt[1];
6849                                                         break;
6850
6851                                                 case 'alt':
6852                                                         $alt = $opt[1];
6853                                                         break;
6854
6855                                                 case 'altclass':
6856                                                         $altclass = $opt[1];
6857                                                         break;
6858
6859                                                 case 'loop':
6860                                                         $loop = $opt[1];
6861                                                         break;
6862
6863                                                 case 'width':
6864                                                         $width = $opt[1];
6865                                                         break;
6866
6867                                                 case 'height':
6868                                                         $height = $opt[1];
6869                                                         break;
6870
6871                                                 case 'bgcolor':
6872                                                         $bgcolor = $opt[1];
6873                                                         break;
6874
6875                                                 case 'mediaplayer':
6876                                                         $mediaplayer = $opt[1];
6877                                                         break;
6878
6879                                                 case 'widescreen':
6880                                                         $widescreen = $opt[1];
6881                                                         break;
6882                                         }
6883                                 }
6884                         }
6885                 }
6886
6887                 $mime = explode('/', $type, 2);
6888                 $mime = $mime[0];
6889
6890                 // Process values for 'auto'
6891                 if ($width == 'auto')
6892                 {
6893                         if ($mime == 'video')
6894                         {
6895                                 if ($height == 'auto')
6896                                 {
6897                                         $width = 480;
6898                                 }
6899                                 elseif ($widescreen)
6900                                 {
6901                                         $width = round((intval($height)/9)*16);
6902                                 }
6903                                 else
6904                                 {
6905                                         $width = round((intval($height)/3)*4);
6906                                 }
6907                         }
6908                         else
6909                         {
6910                                 $width = '100%';
6911                         }
6912                 }
6913
6914                 if ($height == 'auto')
6915                 {
6916                         if ($mime == 'audio')
6917                         {
6918                                 $height = 0;
6919                         }
6920                         elseif ($mime == 'video')
6921                         {
6922                                 if ($width == 'auto')
6923                                 {
6924                                         if ($widescreen)
6925                                         {
6926                                                 $height = 270;
6927                                         }
6928                                         else
6929                                         {
6930                                                 $height = 360;
6931                                         }
6932                                 }
6933                                 elseif ($widescreen)
6934                                 {
6935                                         $height = round((intval($width)/16)*9);
6936                                 }
6937                                 else
6938                                 {
6939                                         $height = round((intval($width)/4)*3);
6940                                 }
6941                         }
6942                         else
6943                         {
6944                                 $height = 376;
6945                         }
6946                 }
6947                 elseif ($mime == 'audio')
6948                 {
6949                         $height = 0;
6950                 }
6951
6952                 // Set proper placeholder value
6953                 if ($mime == 'audio')
6954                 {
6955                         $placeholder = $audio;
6956                 }
6957                 elseif ($mime == 'video')
6958                 {
6959                         $placeholder = $video;
6960                 }
6961
6962                 $embed = '';
6963
6964                 // Make sure the JS library is included
6965                 if (!$native)
6966                 {
6967                         static $javascript_outputted = null;
6968                         if (!$javascript_outputted && $this->javascript)
6969                         {
6970                                 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
6971                                 $javascript_outputted = true;
6972                         }
6973                 }
6974
6975                 // Odeo Feed MP3's
6976                 if ($handler == 'odeo')
6977                 {
6978                         if ($native)
6979                         {
6980                                 $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>';
6981                         }
6982                         else
6983                         {
6984                                 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
6985                         }
6986                 }
6987
6988                 // Flash
6989                 elseif ($handler == 'flash')
6990                 {
6991                         if ($native)
6992                         {
6993                                 $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>";
6994                         }
6995                         else
6996                         {
6997                                 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
6998                         }
6999                 }
7000
7001                 // Flash Media Player file types.
7002                 // Preferred handler for MP3 file types.
7003                 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7004                 {
7005                         $height += 20;
7006                         if ($native)
7007                         {
7008                                 $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>";
7009                         }
7010                         else
7011                         {
7012                                 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7013                         }
7014                 }
7015
7016                 // QuickTime 7 file types.  Need to test with QuickTime 6.
7017                 // Only handle MP3's if the Flash Media Player is not present.
7018                 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7019                 {
7020                         $height += 16;
7021                         if ($native)
7022                         {
7023                                 if ($placeholder != ""){
7024                                         $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>";
7025                                 }
7026                                 else {
7027                                         $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>";
7028                                 }
7029                         }
7030                         else
7031                         {
7032                                 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7033                         }
7034                 }
7035
7036                 // Windows Media
7037                 elseif ($handler == 'wmedia')
7038                 {
7039                         $height += 45;
7040                         if ($native)
7041                         {
7042                                 $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>";
7043                         }
7044                         else
7045                         {
7046                                 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7047                         }
7048                 }
7049
7050                 // Everything else
7051                 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7052
7053                 return $embed;
7054         }
7055
7056         function get_real_type($find_handler = false)
7057         {
7058                 // If it's Odeo, let's get it out of the way.
7059                 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7060                 {
7061                         return 'odeo';
7062                 }
7063
7064                 // Mime-types by handler.
7065                 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7066                 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
7067                 $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
7068                 $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
7069                 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7070
7071                 if ($this->get_type() !== null)
7072                 {
7073                         $type = strtolower($this->type);
7074                 }
7075                 else
7076                 {
7077                         $type = null;
7078                 }
7079
7080                 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7081                 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7082                 {
7083                         switch (strtolower($this->get_extension()))
7084                         {
7085                                 // Audio mime-types
7086                                 case 'aac':
7087                                 case 'adts':
7088                                         $type = 'audio/acc';
7089                                         break;
7090
7091                                 case 'aif':
7092                                 case 'aifc':
7093                                 case 'aiff':
7094                                 case 'cdda':
7095                                         $type = 'audio/aiff';
7096                                         break;
7097
7098                                 case 'bwf':
7099                                         $type = 'audio/wav';
7100                                         break;
7101
7102                                 case 'kar':
7103                                 case 'mid':
7104                                 case 'midi':
7105                                 case 'smf':
7106                                         $type = 'audio/midi';
7107                                         break;
7108
7109                                 case 'm4a':
7110                                         $type = 'audio/x-m4a';
7111                                         break;
7112
7113                                 case 'mp3':
7114                                 case 'swa':
7115                                         $type = 'audio/mp3';
7116                                         break;
7117
7118                                 case 'wav':
7119                                         $type = 'audio/wav';
7120                                         break;
7121
7122                                 case 'wax':
7123                                         $type = 'audio/x-ms-wax';
7124                                         break;
7125
7126                                 case 'wma':
7127                                         $type = 'audio/x-ms-wma';
7128                                         break;
7129
7130                                 // Video mime-types
7131                                 case '3gp':
7132                                 case '3gpp':
7133                                         $type = 'video/3gpp';
7134                                         break;
7135
7136                                 case '3g2':
7137                                 case '3gp2':
7138                                         $type = 'video/3gpp2';
7139                                         break;
7140
7141                                 case 'asf':
7142                                         $type = 'video/x-ms-asf';
7143                                         break;
7144
7145                                 case 'flv':
7146                                         $type = 'video/x-flv';
7147                                         break;
7148
7149                                 case 'm1a':
7150                                 case 'm1s':
7151                                 case 'm1v':
7152                                 case 'm15':
7153                                 case 'm75':
7154                                 case 'mp2':
7155                                 case 'mpa':
7156                                 case 'mpeg':
7157                                 case 'mpg':
7158                                 case 'mpm':
7159                                 case 'mpv':
7160                                         $type = 'video/mpeg';
7161                                         break;
7162
7163                                 case 'm4v':
7164                                         $type = 'video/x-m4v';
7165                                         break;
7166
7167                                 case 'mov':
7168                                 case 'qt':
7169                                         $type = 'video/quicktime';
7170                                         break;
7171
7172                                 case 'mp4':
7173                                 case 'mpg4':
7174                                         $type = 'video/mp4';
7175                                         break;
7176
7177                                 case 'sdv':
7178                                         $type = 'video/sd-video';
7179                                         break;
7180
7181                                 case 'wm':
7182                                         $type = 'video/x-ms-wm';
7183                                         break;
7184
7185                                 case 'wmv':
7186                                         $type = 'video/x-ms-wmv';
7187                                         break;
7188
7189                                 case 'wvx':
7190                                         $type = 'video/x-ms-wvx';
7191                                         break;
7192
7193                                 // Flash mime-types
7194                                 case 'spl':
7195                                         $type = 'application/futuresplash';
7196                                         break;
7197
7198                                 case 'swf':
7199                                         $type = 'application/x-shockwave-flash';
7200                                         break;
7201                         }
7202                 }
7203
7204                 if ($find_handler)
7205                 {
7206                         if (in_array($type, $types_flash))
7207                         {
7208                                 return 'flash';
7209                         }
7210                         elseif (in_array($type, $types_fmedia))
7211                         {
7212                                 return 'fmedia';
7213                         }
7214                         elseif (in_array($type, $types_quicktime))
7215                         {
7216                                 return 'quicktime';
7217                         }
7218                         elseif (in_array($type, $types_wmedia))
7219                         {
7220                                 return 'wmedia';
7221                         }
7222                         elseif (in_array($type, $types_mp3))
7223                         {
7224                                 return 'mp3';
7225                         }
7226                         else
7227                         {
7228                                 return null;
7229                         }
7230                 }
7231                 else
7232                 {
7233                         return $type;
7234                 }
7235         }
7236 }
7237
7238 class SimplePie_Caption
7239 {
7240         var $type;
7241         var $lang;
7242         var $startTime;
7243         var $endTime;
7244         var $text;
7245
7246         // Constructor, used to input the data
7247         function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7248         {
7249                 $this->type = $type;
7250                 $this->lang = $lang;
7251                 $this->startTime = $startTime;
7252                 $this->endTime = $endTime;
7253                 $this->text = $text;
7254         }
7255
7256         function __toString()
7257         {
7258                 // There is no $this->data here
7259                 return md5(serialize($this));
7260         }
7261
7262         function get_endtime()
7263         {
7264                 if ($this->endTime !== null)
7265                 {
7266                         return $this->endTime;
7267                 }
7268                 else
7269                 {
7270                         return null;
7271                 }
7272         }
7273
7274         function get_language()
7275         {
7276                 if ($this->lang !== null)
7277                 {
7278                         return $this->lang;
7279                 }
7280                 else
7281                 {
7282                         return null;
7283                 }
7284         }
7285
7286         function get_starttime()
7287         {
7288                 if ($this->startTime !== null)
7289                 {
7290                         return $this->startTime;
7291                 }
7292                 else
7293                 {
7294                         return null;
7295                 }
7296         }
7297
7298         function get_text()
7299         {
7300                 if ($this->text !== null)
7301                 {
7302                         return $this->text;
7303                 }
7304                 else
7305                 {
7306                         return null;
7307                 }
7308         }
7309
7310         function get_type()
7311         {
7312                 if ($this->type !== null)
7313                 {
7314                         return $this->type;
7315                 }
7316                 else
7317                 {
7318                         return null;
7319                 }
7320         }
7321 }
7322
7323 class SimplePie_Credit
7324 {
7325         var $role;
7326         var $scheme;
7327         var $name;
7328
7329         // Constructor, used to input the data
7330         function SimplePie_Credit($role = null, $scheme = null, $name = null)
7331         {
7332                 $this->role = $role;
7333                 $this->scheme = $scheme;
7334                 $this->name = $name;
7335         }
7336
7337         function __toString()
7338         {
7339                 // There is no $this->data here
7340                 return md5(serialize($this));
7341         }
7342
7343         function get_role()
7344         {
7345                 if ($this->role !== null)
7346                 {
7347                         return $this->role;
7348                 }
7349                 else
7350                 {
7351                         return null;
7352                 }
7353         }
7354
7355         function get_scheme()
7356         {
7357                 if ($this->scheme !== null)
7358                 {
7359                         return $this->scheme;
7360                 }
7361                 else
7362                 {
7363                         return null;
7364                 }
7365         }
7366
7367         function get_name()
7368         {
7369                 if ($this->name !== null)
7370                 {
7371                         return $this->name;
7372                 }
7373                 else
7374                 {
7375                         return null;
7376                 }
7377         }
7378 }
7379
7380 class SimplePie_Copyright
7381 {
7382         var $url;
7383         var $label;
7384
7385         // Constructor, used to input the data
7386         function SimplePie_Copyright($url = null, $label = null)
7387         {
7388                 $this->url = $url;
7389                 $this->label = $label;
7390         }
7391
7392         function __toString()
7393         {
7394                 // There is no $this->data here
7395                 return md5(serialize($this));
7396         }
7397
7398         function get_url()
7399         {
7400                 if ($this->url !== null)
7401                 {
7402                         return $this->url;
7403                 }
7404                 else
7405                 {
7406                         return null;
7407                 }
7408         }
7409
7410         function get_attribution()
7411         {
7412                 if ($this->label !== null)
7413                 {
7414                         return $this->label;
7415                 }
7416                 else
7417                 {
7418                         return null;
7419                 }
7420         }
7421 }
7422
7423 class SimplePie_Rating
7424 {
7425         var $scheme;
7426         var $value;
7427
7428         // Constructor, used to input the data
7429         function SimplePie_Rating($scheme = null, $value = null)
7430         {
7431                 $this->scheme = $scheme;
7432                 $this->value = $value;
7433         }
7434
7435         function __toString()
7436         {
7437                 // There is no $this->data here
7438                 return md5(serialize($this));
7439         }
7440
7441         function get_scheme()
7442         {
7443                 if ($this->scheme !== null)
7444                 {
7445                         return $this->scheme;
7446                 }
7447                 else
7448                 {
7449                         return null;
7450                 }
7451         }
7452
7453         function get_value()
7454         {
7455                 if ($this->value !== null)
7456                 {
7457                         return $this->value;
7458                 }
7459                 else
7460                 {
7461                         return null;
7462                 }
7463         }
7464 }
7465
7466 class SimplePie_Restriction
7467 {
7468         var $relationship;
7469         var $type;
7470         var $value;
7471
7472         // Constructor, used to input the data
7473         function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7474         {
7475                 $this->relationship = $relationship;
7476                 $this->type = $type;
7477                 $this->value = $value;
7478         }
7479
7480         function __toString()
7481         {
7482                 // There is no $this->data here
7483                 return md5(serialize($this));
7484         }
7485
7486         function get_relationship()
7487         {
7488                 if ($this->relationship !== null)
7489                 {
7490                         return $this->relationship;
7491                 }
7492                 else
7493                 {
7494                         return null;
7495                 }
7496         }
7497
7498         function get_type()
7499         {
7500                 if ($this->type !== null)
7501                 {
7502                         return $this->type;
7503                 }
7504                 else
7505                 {
7506                         return null;
7507                 }
7508         }
7509
7510         function get_value()
7511         {
7512                 if ($this->value !== null)
7513                 {
7514                         return $this->value;
7515                 }
7516                 else
7517                 {
7518                         return null;
7519                 }
7520         }
7521 }
7522
7523 /**
7524  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7525  */
7526 class SimplePie_File
7527 {
7528         var $url;
7529         var $useragent;
7530         var $success = true;
7531         var $headers = array();
7532         var $body;
7533         var $status_code;
7534         var $redirects = 0;
7535         var $error;
7536         var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7537
7538         function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7539         {
7540                 if (class_exists('idna_convert'))
7541                 {
7542                         $idn =& new idna_convert;
7543                         $parsed = SimplePie_Misc::parse_url($url);
7544                         $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7545                 }
7546                 $this->url = $url;
7547                 $this->useragent = $useragent;
7548                 if (preg_match('/^http(s)?:\/\//i', $url))
7549                 {
7550                         if ($useragent === null)
7551                         {
7552                                 $useragent = ini_get('user_agent');
7553                                 $this->useragent = $useragent;
7554                         }
7555                         if (!is_array($headers))
7556                         {
7557                                 $headers = array();
7558                         }
7559                         if (!$force_fsockopen && function_exists('curl_exec'))
7560                         {
7561                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7562                                 $fp = curl_init();
7563                                 $headers2 = array();
7564                                 foreach ($headers as $key => $value)
7565                                 {
7566                                         $headers2[] = "$key: $value";
7567                                 }
7568                                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7569                                 {
7570                                         curl_setopt($fp, CURLOPT_ENCODING, '');
7571                                 }
7572                                 curl_setopt($fp, CURLOPT_URL, $url);
7573                                 curl_setopt($fp, CURLOPT_HEADER, 1);
7574                                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7575                                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7576                                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7577                                 curl_setopt($fp, CURLOPT_REFERER, $url);
7578                                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7579                                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7580                                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7581                                 {
7582                                         curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7583                                         curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7584                                 }
7585
7586                                 $this->headers = curl_exec($fp);
7587                                 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7588                                 {
7589                                         curl_setopt($fp, CURLOPT_ENCODING, 'none');
7590                                         $this->headers = curl_exec($fp);
7591                                 }
7592                                 if (curl_errno($fp))
7593                                 {
7594                                         $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7595                                         $this->success = false;
7596                                 }
7597                                 else
7598                                 {
7599                                         $info = curl_getinfo($fp);
7600                                         curl_close($fp);
7601                                         $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7602                                         $this->headers = array_pop($this->headers);
7603                                         $parser =& new SimplePie_HTTP_Parser($this->headers);
7604                                         if ($parser->parse())
7605                                         {
7606                                                 $this->headers = $parser->headers;
7607                                                 $this->body = $parser->body;
7608                                                 $this->status_code = $parser->status_code;
7609                                                 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)
7610                                                 {
7611                                                         $this->redirects++;
7612                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7613                                                         return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7614                                                 }
7615                                         }
7616                                 }
7617                         }
7618                         else
7619                         {
7620                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7621                                 $url_parts = parse_url($url);
7622                                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7623                                 {
7624                                         $url_parts['host'] = "ssl://$url_parts[host]";
7625                                         $url_parts['port'] = 443;
7626                                 }
7627                                 if (!isset($url_parts['port']))
7628                                 {
7629                                         $url_parts['port'] = 80;
7630                                 }
7631                                 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7632                                 if (!$fp)
7633                                 {
7634                                         $this->error = 'fsockopen error: ' . $errstr;
7635                                         $this->success = false;
7636                                 }
7637                                 else
7638                                 {
7639                                         stream_set_timeout($fp, $timeout);
7640                                         if (isset($url_parts['path']))
7641                                         {
7642                                                 if (isset($url_parts['query']))
7643                                                 {
7644                                                         $get = "$url_parts[path]?$url_parts[query]";
7645                                                 }
7646                                                 else
7647                                                 {
7648                                                         $get = $url_parts['path'];
7649                                                 }
7650                                         }
7651                                         else
7652                                         {
7653                                                 $get = '/';
7654                                         }
7655                                         $out = "GET $get HTTP/1.0\r\n";
7656                                         $out .= "Host: $url_parts[host]\r\n";
7657                                         $out .= "User-Agent: $useragent\r\n";
7658                                         if (function_exists('gzinflate'))
7659                                         {
7660                                                 $out .= "Accept-Encoding: gzip,deflate\r\n";
7661                                         }
7662
7663                                         if (isset($url_parts['user']) && isset($url_parts['pass']))
7664                                         {
7665                                                 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7666                                         }
7667                                         foreach ($headers as $key => $value)
7668                                         {
7669                                                 $out .= "$key: $value\r\n";
7670                                         }
7671                                         $out .= "Connection: Close\r\n\r\n";
7672                                         fwrite($fp, $out);
7673
7674                                         $info = stream_get_meta_data($fp);
7675
7676                                         $this->headers = '';
7677                                         while (!$info['eof'] && !$info['timed_out'])
7678                                         {
7679                                                 $this->headers .= fread($fp, 1160);
7680                                                 $info = stream_get_meta_data($fp);
7681                                         }
7682                                         if (!$info['timed_out'])
7683                                         {
7684                                                 $parser =& new SimplePie_HTTP_Parser($this->headers);
7685                                                 if ($parser->parse())
7686                                                 {
7687                                                         $this->headers = $parser->headers;
7688                                                         $this->body = $parser->body;
7689                                                         $this->status_code = $parser->status_code;
7690                                                         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)
7691                                                         {
7692                                                                 $this->redirects++;
7693                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7694                                                                 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7695                                                         }
7696                                                         if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
7697                                                         {
7698                                                                 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
7699                                                                 {
7700                                                                         $this->body = substr($this->body, 10);
7701                                                                 }
7702                                                                 $this->body = gzinflate($this->body);
7703                                                         }
7704                                                 }
7705                                         }
7706                                         else
7707                                         {
7708                                                 $this->error = 'fsocket timed out';
7709                                                 $this->success = false;
7710                                         }
7711                                         fclose($fp);
7712                                 }
7713                         }
7714                 }
7715                 else
7716                 {
7717                         $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7718                         if (!$this->body = file_get_contents($url))
7719                         {
7720                                 $this->error = 'file_get_contents could not read the file';
7721                                 $this->success = false;
7722                         }
7723                 }
7724         }
7725 }
7726
7727 /**
7728  * HTTP Response Parser
7729  *
7730  * @package SimplePie
7731  */
7732 class SimplePie_HTTP_Parser
7733 {
7734         /**
7735          * HTTP Version
7736          *
7737          * @access public
7738          * @var float
7739          */
7740         var $http_version = 0.0;
7741
7742         /**
7743          * Status code
7744          *
7745          * @access public
7746          * @var int
7747          */
7748         var $status_code = 0;
7749
7750         /**
7751          * Reason phrase
7752          *
7753          * @access public
7754          * @var string
7755          */
7756         var $reason = '';
7757
7758         /**
7759          * Key/value pairs of the headers
7760          *
7761          * @access public
7762          * @var array
7763          */
7764         var $headers = array();
7765
7766         /**
7767          * Body of the response
7768          *
7769          * @access public
7770          * @var string
7771          */
7772         var $body = '';
7773
7774         /**
7775          * Current state of the state machine
7776          *
7777          * @access private
7778          * @var string
7779          */
7780         var $state = 'http_version';
7781
7782         /**
7783          * Input data
7784          *
7785          * @access private
7786          * @var string
7787          */
7788         var $data = '';
7789
7790         /**
7791          * Input data length (to avoid calling strlen() everytime this is needed)
7792          *
7793          * @access private
7794          * @var int
7795          */
7796         var $data_length = 0;
7797
7798         /**
7799          * Current position of the pointer
7800          *
7801          * @var int
7802          * @access private
7803          */
7804         var $position = 0;
7805
7806         /**
7807          * Name of the hedaer currently being parsed
7808          *
7809          * @access private
7810          * @var string
7811          */
7812         var $name = '';
7813
7814         /**
7815          * Value of the hedaer currently being parsed
7816          *
7817          * @access private
7818          * @var string
7819          */
7820         var $value = '';
7821
7822         /**
7823          * Create an instance of the class with the input data
7824          *
7825          * @access public
7826          * @param string $data Input data
7827          */
7828         function SimplePie_HTTP_Parser($data)
7829         {
7830                 $this->data = $data;
7831                 $this->data_length = strlen($this->data);
7832         }
7833
7834         /**
7835          * Parse the input data
7836          *
7837          * @access public
7838          * @return bool true on success, false on failure
7839          */
7840         function parse()
7841         {
7842                 while ($this->state && $this->state !== 'emit' && $this->has_data())
7843                 {
7844                         $state = $this->state;
7845                         $this->$state();
7846                 }
7847                 $this->data = '';
7848                 if ($this->state === 'emit')
7849                 {
7850                         return true;
7851                 }
7852                 else
7853                 {
7854                         $this->http_version = '';
7855                         $this->status_code = '';
7856                         $this->reason = '';
7857                         $this->headers = array();
7858                         $this->body = '';
7859                         return false;
7860                 }
7861         }
7862
7863         /**
7864          * Check whether there is data beyond the pointer
7865          *
7866          * @access private
7867          * @return bool true if there is further data, false if not
7868          */
7869         function has_data()
7870         {
7871                 return (bool) ($this->position < $this->data_length);
7872         }
7873
7874         /**
7875          * See if the next character is LWS
7876          *
7877          * @access private
7878          * @return bool true if the next character is LWS, false if not
7879          */
7880         function is_linear_whitespace()
7881         {
7882                 return (bool) ($this->data[$this->position] === "\x09"
7883                         || $this->data[$this->position] === "\x20"
7884                         || ($this->data[$this->position] === "\x0A"
7885                                 && isset($this->data[$this->position + 1])
7886                                 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7887         }
7888
7889         /**
7890          * Parse the HTTP version
7891          *
7892          * @access private
7893          */
7894         function http_version()
7895         {
7896                 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7897                 {
7898                         $len = strspn($this->data, '0123456789.', 5);
7899                         $this->http_version = substr($this->data, 5, $len);
7900                         $this->position += 5 + $len;
7901                         if (substr_count($this->http_version, '.') <= 1)
7902                         {
7903                                 $this->http_version = (float) $this->http_version;
7904                                 $this->position += strspn($this->data, "\x09\x20", $this->position);
7905                                 $this->state = 'status';
7906                         }
7907                         else
7908                         {
7909                                 $this->state = false;
7910                         }
7911                 }
7912                 else
7913                 {
7914                         $this->state = false;
7915                 }
7916         }
7917
7918         /**
7919          * Parse the status code
7920          *
7921          * @access private
7922          */
7923         function status()
7924         {
7925                 if ($len = strspn($this->data, '0123456789', $this->position))
7926                 {
7927                         $this->status_code = (int) substr($this->data, $this->position, $len);
7928                         $this->position += $len;
7929                         $this->state = 'reason';
7930                 }
7931                 else
7932                 {
7933                         $this->state = false;
7934                 }
7935         }
7936
7937         /**
7938          * Parse the reason phrase
7939          *
7940          * @access private
7941          */
7942         function reason()
7943         {
7944                 $len = strcspn($this->data, "\x0A", $this->position);
7945                 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
7946                 $this->position += $len + 1;
7947                 $this->state = 'new_line';
7948         }
7949
7950         /**
7951          * Deal with a new line, shifting data around as needed
7952          *
7953          * @access private
7954          */
7955         function new_line()
7956         {
7957                 $this->value = trim($this->value, "\x0D\x20");
7958                 if ($this->name !== '' && $this->value !== '')
7959                 {
7960                         $this->name = strtolower($this->name);
7961                         if (isset($this->headers[$this->name]))
7962                         {
7963                                 $this->headers[$this->name] .= ', ' . $this->value;
7964                         }
7965                         else
7966                         {
7967                                 $this->headers[$this->name] = $this->value;
7968                         }
7969                 }
7970                 $this->name = '';
7971                 $this->value = '';
7972                 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
7973                 {
7974                         $this->position += 2;
7975                         $this->state = 'body';
7976                 }
7977                 elseif ($this->data[$this->position] === "\x0A")
7978                 {
7979                         $this->position++;
7980                         $this->state = 'body';
7981                 }
7982                 else
7983                 {
7984                         $this->state = 'name';
7985                 }
7986         }
7987
7988         /**
7989          * Parse a header name
7990          *
7991          * @access private
7992          */
7993         function name()
7994         {
7995                 $len = strcspn($this->data, "\x0A:", $this->position);
7996                 if (isset($this->data[$this->position + $len]))
7997                 {
7998                         if ($this->data[$this->position + $len] === "\x0A")
7999                         {
8000                                 $this->position += $len;
8001                                 $this->state = 'new_line';
8002                         }
8003                         else
8004                         {
8005                                 $this->name = substr($this->data, $this->position, $len);
8006                                 $this->position += $len + 1;
8007                                 $this->state = 'value';
8008                         }
8009                 }
8010                 else
8011                 {
8012                         $this->state = false;
8013                 }
8014         }
8015
8016         /**
8017          * Parse LWS, replacing consecutive LWS characters with a single space
8018          *
8019          * @access private
8020          */
8021         function linear_whitespace()
8022         {
8023                 do
8024                 {
8025                         if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8026                         {
8027                                 $this->position += 2;
8028                         }
8029                         elseif ($this->data[$this->position] === "\x0A")
8030                         {
8031                                 $this->position++;
8032                         }
8033                         $this->position += strspn($this->data, "\x09\x20", $this->position);
8034                 } while ($this->has_data() && $this->is_linear_whitespace());
8035                 $this->value .= "\x20";
8036         }
8037
8038         /**
8039          * See what state to move to while within non-quoted header values
8040          *
8041          * @access private
8042          */
8043         function value()
8044         {
8045                 if ($this->is_linear_whitespace())
8046                 {
8047                         $this->linear_whitespace();
8048                 }
8049                 else
8050                 {
8051                         switch ($this->data[$this->position])
8052                         {
8053                                 case '"':
8054                                         $this->position++;
8055                                         $this->state = 'quote';
8056                                         break;
8057
8058                                 case "\x0A":
8059                                         $this->position++;
8060                                         $this->state = 'new_line';
8061                                         break;
8062
8063                                 default:
8064                                         $this->state = 'value_char';
8065                                         break;
8066                         }
8067                 }
8068         }
8069
8070         /**
8071          * Parse a header value while outside quotes
8072          *
8073          * @access private
8074          */
8075         function value_char()
8076         {
8077                 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8078                 $this->value .= substr($this->data, $this->position, $len);
8079                 $this->position += $len;
8080                 $this->state = 'value';
8081         }
8082
8083         /**
8084          * See what state to move to while within quoted header values
8085          *
8086          * @access private
8087          */
8088         function quote()
8089         {
8090                 if ($this->is_linear_whitespace())
8091                 {
8092                         $this->linear_whitespace();
8093                 }
8094                 else
8095                 {
8096                         switch ($this->data[$this->position])
8097                         {
8098                                 case '"':
8099                                         $this->position++;
8100                                         $this->state = 'value';
8101                                         break;
8102
8103                                 case "\x0A":
8104                                         $this->position++;
8105                                         $this->state = 'new_line';
8106                                         break;
8107
8108                                 case '\\':
8109                                         $this->position++;
8110                                         $this->state = 'quote_escaped';
8111                                         break;
8112
8113                                 default:
8114                                         $this->state = 'quote_char';
8115                                         break;
8116                         }
8117                 }
8118         }
8119
8120         /**
8121          * Parse a header value while within quotes
8122          *
8123          * @access private
8124          */
8125         function quote_char()
8126         {
8127                 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8128                 $this->value .= substr($this->data, $this->position, $len);
8129                 $this->position += $len;
8130                 $this->state = 'value';
8131         }
8132
8133         /**
8134          * Parse an escaped character within quotes
8135          *
8136          * @access private
8137          */
8138         function quote_escaped()
8139         {
8140                 $this->value .= $this->data[$this->position];
8141                 $this->position++;
8142                 $this->state = 'quote';
8143         }
8144
8145         /**
8146          * Parse the body
8147          *
8148          * @access private
8149          */
8150         function body()
8151         {
8152                 $this->body = substr($this->data, $this->position);
8153                 $this->state = 'emit';
8154         }
8155 }
8156
8157 class SimplePie_Cache
8158 {
8159         /**
8160          * Don't call the constructor. Please.
8161          *
8162          * @access private
8163          */
8164         function SimplePie_Cache()
8165         {
8166                 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8167         }
8168
8169         /**
8170          * Create a new SimplePie_Cache object
8171          *
8172          * @static
8173          * @access public
8174          */
8175         function create($location, $filename, $extension)
8176         {
8177                 return new SimplePie_Cache_File($location, $filename, $extension);
8178         }
8179 }
8180
8181 class SimplePie_Cache_File
8182 {
8183         var $location;
8184         var $filename;
8185         var $extension;
8186         var $name;
8187
8188         function SimplePie_Cache_File($location, $filename, $extension)
8189         {
8190                 $this->location = $location;
8191                 $this->filename = rawurlencode($filename);
8192                 $this->extension = rawurlencode($extension);
8193                 $this->name = "$location/$this->filename.$this->extension";
8194         }
8195
8196         function save($data)
8197         {
8198                 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8199                 {
8200                         if (is_a($data, 'SimplePie'))
8201                         {
8202                                 $data = $data->data;
8203                         }
8204
8205                         $data = serialize($data);
8206
8207                         if (function_exists('file_put_contents'))
8208                         {
8209                                 return (bool) file_put_contents($this->name, $data);
8210                         }
8211                         else
8212                         {
8213                                 $fp = fopen($this->name, 'wb');
8214                                 if ($fp)
8215                                 {
8216                                         fwrite($fp, $data);
8217                                         fclose($fp);
8218                                         return true;
8219                                 }
8220                         }
8221                 }
8222                 return false;
8223         }
8224
8225         function load()
8226         {
8227                 if (file_exists($this->name) && is_readable($this->name))
8228                 {
8229                         return unserialize(file_get_contents($this->name));
8230                 }
8231                 return false;
8232         }
8233
8234         function mtime()
8235         {
8236                 if (file_exists($this->name))
8237                 {
8238                         return filemtime($this->name);
8239                 }
8240                 return false;
8241         }
8242
8243         function touch()
8244         {
8245                 if (file_exists($this->name))
8246                 {
8247                         return touch($this->name);
8248                 }
8249                 return false;
8250         }
8251
8252         function unlink()
8253         {
8254                 if (file_exists($this->name))
8255                 {
8256                         return unlink($this->name);
8257                 }
8258                 return false;
8259         }
8260 }
8261
8262 class SimplePie_Misc
8263 {
8264         function time_hms($seconds)
8265         {
8266                 $time = '';
8267
8268                 $hours = floor($seconds / 3600);
8269                 $remainder = $seconds % 3600;
8270                 if ($hours > 0)
8271                 {
8272                         $time .= $hours.':';
8273                 }
8274
8275                 $minutes = floor($remainder / 60);
8276                 $seconds = $remainder % 60;
8277                 if ($minutes < 10 && $hours > 0)
8278                 {
8279                         $minutes = '0' . $minutes;
8280                 }
8281                 if ($seconds < 10)
8282                 {
8283                         $seconds = '0' . $seconds;
8284                 }
8285
8286                 $time .= $minutes.':';
8287                 $time .= $seconds;
8288
8289                 return $time;
8290         }
8291
8292         function absolutize_url($relative, $base)
8293         {
8294                 if ($relative !== '')
8295                 {
8296                         $relative = SimplePie_Misc::parse_url($relative);
8297                         if ($relative['scheme'] !== '')
8298                         {
8299                                 $target = $relative;
8300                         }
8301                         elseif ($base !== '')
8302                         {
8303                                 $base = SimplePie_Misc::parse_url($base);
8304                                 $target = SimplePie_Misc::parse_url('');
8305                                 if ($relative['authority'] !== '')
8306                                 {
8307                                         $target = $relative;
8308                                         $target['scheme'] = $base['scheme'];
8309                                 }
8310                                 else
8311                                 {
8312                                         $target['scheme'] = $base['scheme'];
8313                                         $target['authority'] = $base['authority'];
8314                                         if ($relative['path'] !== '')
8315                                         {
8316                                                 if (strpos($relative['path'], '/') === 0)
8317                                                 {
8318                                                         $target['path'] = $relative['path'];
8319                                                 }
8320                                                 elseif ($base['authority'] !== '' && $base['path'] === '')
8321                                                 {
8322                                                         $target['path'] = '/' . $relative['path'];
8323                                                 }
8324                                                 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8325                                                 {
8326                                                         $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8327                                                 }
8328                                                 else
8329                                                 {
8330                                                         $target['path'] = $relative['path'];
8331                                                 }
8332                                                 $target['query'] = $relative['query'];
8333                                         }
8334                                         else
8335                                         {
8336                                                 $target['path'] = $base['path'];
8337                                                 if ($relative['query'] !== '')
8338                                                 {
8339                                                         $target['query'] = $relative['query'];
8340                                                 }
8341                                                 elseif ($base['query'] !== '')
8342                                                 {
8343                                                         $target['query'] = $base['query'];
8344                                                 }
8345                                         }
8346                                 }
8347                                 $target['fragment'] = $relative['fragment'];
8348                         }
8349                         else
8350                         {
8351                                 // No base URL, just return the relative URL
8352                                 $target = $relative;
8353                         }
8354                         $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8355                 }
8356                 else
8357                 {
8358                         $return = $base;
8359                 }
8360                 $return = SimplePie_Misc::normalize_url($return);
8361                 return $return;
8362         }
8363
8364         function remove_dot_segments($input)
8365         {
8366                 $output = '';
8367                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8368                 {
8369                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8370                         if (strpos($input, '../') === 0)
8371                         {
8372                                 $input = substr($input, 3);
8373                         }
8374                         elseif (strpos($input, './') === 0)
8375                         {
8376                                 $input = substr($input, 2);
8377                         }
8378                         // 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,
8379                         elseif (strpos($input, '/./') === 0)
8380                         {
8381                                 $input = substr_replace($input, '/', 0, 3);
8382                         }
8383                         elseif ($input == '/.')
8384                         {
8385                                 $input = '/';
8386                         }
8387                         // 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,
8388                         elseif (strpos($input, '/../') === 0)
8389                         {
8390                                 $input = substr_replace($input, '/', 0, 4);
8391                                 $output = substr_replace($output, '', strrpos($output, '/'));
8392                         }
8393                         elseif ($input == '/..')
8394                         {
8395                                 $input = '/';
8396                                 $output = substr_replace($output, '', strrpos($output, '/'));
8397                         }
8398                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8399                         elseif ($input == '.' || $input == '..')
8400                         {
8401                                 $input = '';
8402                         }
8403                         // 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
8404                         elseif (($pos = strpos($input, '/', 1)) !== false)
8405                         {
8406                                 $output .= substr($input, 0, $pos);
8407                                 $input = substr_replace($input, '', 0, $pos);
8408                         }
8409                         else
8410                         {
8411                                 $output .= $input;
8412                                 $input = '';
8413                         }
8414                 }
8415                 return $output . $input;
8416         }
8417
8418         function get_element($realname, $string)
8419         {
8420                 $return = array();
8421                 $name = preg_quote($realname, '/');
8422                 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8423                 {
8424                         for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8425                         {
8426                                 $return[$i]['tag'] = $realname;
8427                                 $return[$i]['full'] = $matches[$i][0][0];
8428                                 $return[$i]['offset'] = $matches[$i][0][1];
8429                                 if (strlen($matches[$i][3][0]) <= 2)
8430                                 {
8431                                         $return[$i]['self_closing'] = true;
8432                                 }
8433                                 else
8434                                 {
8435                                         $return[$i]['self_closing'] = false;
8436                                         $return[$i]['content'] = $matches[$i][4][0];
8437                                 }
8438                                 $return[$i]['attribs'] = array();
8439                                 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))
8440                                 {
8441                                         for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8442                                         {
8443                                                 if (count($attribs[$j]) == 2)
8444                                                 {
8445                                                         $attribs[$j][2] = $attribs[$j][1];
8446                                                 }
8447                                                 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8448                                         }
8449                                 }
8450                         }
8451                 }
8452                 return $return;
8453         }
8454
8455         function element_implode($element)
8456         {
8457                 $full = "<$element[tag]";
8458                 foreach ($element['attribs'] as $key => $value)
8459                 {
8460                         $key = strtolower($key);
8461                         $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8462                 }
8463                 if ($element['self_closing'])
8464                 {
8465                         $full .= ' />';
8466                 }
8467                 else
8468                 {
8469                         $full .= ">$element[content]</$element[tag]>";
8470                 }
8471                 return $full;
8472         }
8473
8474         function error($message, $level, $file, $line)
8475         {
8476                 switch ($level)
8477                 {
8478                         case E_USER_ERROR:
8479                                 $note = 'PHP Error';
8480                                 break;
8481                         case E_USER_WARNING:
8482                                 $note = 'PHP Warning';
8483                                 break;
8484                         case E_USER_NOTICE:
8485                                 $note = 'PHP Notice';
8486                                 break;
8487                         default:
8488                                 $note = 'Unknown Error';
8489                                 break;
8490                 }
8491                 error_log("$note: $message in $file on line $line", 0);
8492                 return $message;
8493         }
8494
8495         /**
8496          * If a file has been cached, retrieve and display it.
8497          *
8498          * This is most useful for caching images (get_favicon(), etc.),
8499          * however it works for all cached files.  This WILL NOT display ANY
8500          * file/image/page/whatever, but rather only display what has already
8501          * been cached by SimplePie.
8502          *
8503          * @access public
8504          * @see SimplePie::get_favicon()
8505          * @param str $identifier_url URL that is used to identify the content.
8506          * This may or may not be the actual URL of the live content.
8507          * @param str $cache_location Location of SimplePie's cache.  Defaults
8508          * to './cache'.
8509          * @param str $cache_extension The file extension that the file was
8510          * cached with.  Defaults to 'spc'.
8511          * @param str $cache_class Name of the cache-handling class being used
8512          * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
8513          * as-is unless you've overloaded the class.
8514          * @param str $cache_name_function Obsolete. Exists for backwards
8515          * compatibility reasons only.
8516          */
8517         function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8518         {
8519                 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8520
8521                 if ($file = $cache->load())
8522                 {
8523                         if (isset($file['headers']['content-type']))
8524                         {
8525                                 header('Content-type:' . $file['headers']['content-type']);
8526                         }
8527                         else
8528                         {
8529                                 header('Content-type: application/octet-stream');
8530                         }
8531                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8532                         echo $file['body'];
8533                         exit;
8534                 }
8535
8536                 die('Cached file for ' . $identifier_url . ' cannot be found.');
8537         }
8538
8539         function fix_protocol($url, $http = 1)
8540         {
8541                 $url = SimplePie_Misc::normalize_url($url);
8542                 $parsed = SimplePie_Misc::parse_url($url);
8543                 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8544                 {
8545                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8546                 }
8547
8548                 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8549                 {
8550                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8551                 }
8552
8553                 if ($http == 2 && $parsed['scheme'] !== '')
8554                 {
8555                         return "feed:$url";
8556                 }
8557                 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8558                 {
8559                         return substr_replace($url, 'podcast', 0, 4);
8560                 }
8561                 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8562                 {
8563                         return substr_replace($url, 'itpc', 0, 4);
8564                 }
8565                 else
8566                 {
8567                         return $url;
8568                 }
8569         }
8570
8571         function parse_url($url)
8572         {
8573                 static $cache = array();
8574                 if (isset($cache[$url]))
8575                 {
8576                         return $cache[$url];
8577                 }
8578                 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8579                 {
8580                         for ($i = count($match); $i <= 9; $i++)
8581                         {
8582                                 $match[$i] = '';
8583                         }
8584                         return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8585                 }
8586                 else
8587                 {
8588                         return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8589                 }
8590         }
8591
8592         function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8593         {
8594                 $return = '';
8595                 if ($scheme !== '')
8596                 {
8597                         $return .= "$scheme:";
8598                 }
8599                 if ($authority !== '')
8600                 {
8601                         $return .= "//$authority";
8602                 }
8603                 if ($path !== '')
8604                 {
8605                         $return .= $path;
8606                 }
8607                 if ($query !== '')
8608                 {
8609                         $return .= "?$query";
8610                 }
8611                 if ($fragment !== '')
8612                 {
8613                         $return .= "#$fragment";
8614                 }
8615                 return $return;
8616         }
8617
8618         function normalize_url($url)
8619         {
8620                 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8621                 $url = SimplePie_Misc::parse_url($url);
8622                 $url['scheme'] = strtolower($url['scheme']);
8623                 if ($url['authority'] !== '')
8624                 {
8625                         $url['authority'] = strtolower($url['authority']);
8626                         $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8627                 }
8628                 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
8629         }
8630
8631         function percent_encoding_normalization($match)
8632         {
8633                 $integer = hexdec($match[1]);
8634                 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
8635                 {
8636                         return chr($integer);
8637                 }
8638                 else
8639                 {
8640                         return strtoupper($match[0]);
8641                 }
8642         }
8643
8644         /**
8645          * Remove bad UTF-8 bytes
8646          *
8647          * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
8648          * FAQ: Multilingual Forms (modified to include full ASCII range)
8649          *
8650          * @author Geoffrey Sneddon
8651          * @see http://www.w3.org/International/questions/qa-forms-utf-8
8652          * @param string $str String to remove bad UTF-8 bytes from
8653          * @return string UTF-8 string
8654          */
8655         function utf8_bad_replace($str)
8656         {
8657                 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
8658                 {
8659                         return $return;
8660                 }
8661                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
8662                 {
8663                         return $return;
8664                 }
8665                 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))
8666                 {
8667                         return implode("\xEF\xBF\xBD", $matches[0]);
8668                 }
8669                 elseif ($str !== '')
8670                 {
8671                         return "\xEF\xBF\xBD";
8672                 }
8673                 else
8674                 {
8675                         return '';
8676                 }
8677         }
8678         
8679         /**
8680          * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8681          *
8682          * @static
8683          * @access public
8684          * @param string $string Windows-1252 encoded string
8685          * @return string UTF-8 encoded string
8686          */
8687         function windows_1252_to_utf8($string)
8688         {
8689                 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");
8690                 
8691                 return strtr($string, $convert_table);
8692         }
8693
8694         function change_encoding($data, $input, $output)
8695         {
8696                 $input = SimplePie_Misc::encoding($input);
8697                 $output = SimplePie_Misc::encoding($output);
8698                 
8699                 // We fail to fail on non US-ASCII bytes
8700                 if ($input === 'US-ASCII')
8701                 {
8702                         static $non_ascii_octects = '';
8703                         if (!$non_ascii_octects)
8704                         {
8705                                 for ($i = 0x80; $i <= 0xFF; $i++)
8706                                 {
8707                                         $non_ascii_octects .= chr($i);
8708                                 }
8709                         }
8710                         $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8711                 }
8712
8713                 if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
8714                 {
8715                         return $return;
8716                 }
8717                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
8718                 {
8719                         return $return;
8720                 }
8721                 elseif ($input == 'windows-1252' && $output == 'UTF-8')
8722                 {
8723                         return SimplePie_Misc::windows_1252_to_utf8($data);
8724                 }
8725                 elseif ($input == 'UTF-8' && $output == 'windows-1252')
8726                 {
8727                         return utf8_decode($data);
8728                 }
8729                 return $data;
8730         }
8731
8732         function encoding($encoding)
8733         {
8734                 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
8735                 switch (strtoupper($encoding))
8736                 {
8737                         case 'ANSI_X3.110-1983':
8738                         case 'CSA_T500-1983':
8739                         case 'CSISO99NAPLPS':
8740                         case 'ISO-IR-99':
8741                         case 'NAPLPS':
8742                                 return 'ANSI_X3.110-1983';
8743         
8744                         case 'ARABIC7':
8745                         case 'ASMO_449':
8746                         case 'CSISO89ASMO449':
8747                         case 'ISO-IR-89':
8748                         case 'ISO_9036':
8749                                 return 'ASMO_449';
8750         
8751                         case 'ADOBE-STANDARD-ENCODING':
8752                         case 'CSADOBESTANDARDENCODING':
8753                                 return 'Adobe-Standard-Encoding';
8754         
8755                         case 'ADOBE-SYMBOL-ENCODING':
8756                         case 'CSHPPSMATH':
8757                                 return 'Adobe-Symbol-Encoding';
8758         
8759                         case 'AMI-1251':
8760                         case 'AMI1251':
8761                         case 'AMIGA-1251':
8762                         case 'AMIGA1251':
8763                                 return 'Amiga-1251';
8764         
8765                         case 'BOCU-1':
8766                         case 'CSBOCU-1':
8767                                 return 'BOCU-1';
8768         
8769                         case 'BRF':
8770                         case 'CSBRF':
8771                                 return 'BRF';
8772         
8773                         case 'BS_4730':
8774                         case 'CSISO4UNITEDKINGDOM':
8775                         case 'GB':
8776                         case 'ISO-IR-4':
8777                         case 'ISO646-GB':
8778                         case 'UK':
8779                                 return 'BS_4730';
8780         
8781                         case 'BS_VIEWDATA':
8782                         case 'CSISO47BSVIEWDATA':
8783                         case 'ISO-IR-47':
8784                                 return 'BS_viewdata';
8785         
8786                         case 'BIG5':
8787                         case 'CSBIG5':
8788                                 return 'Big5';
8789         
8790                         case 'BIG5-HKSCS':
8791                                 return 'Big5-HKSCS';
8792         
8793                         case 'CESU-8':
8794                         case 'CSCESU-8':
8795                                 return 'CESU-8';
8796         
8797                         case 'CA':
8798                         case 'CSA7-1':
8799                         case 'CSA_Z243.4-1985-1':
8800                         case 'CSISO121CANADIAN1':
8801                         case 'ISO-IR-121':
8802                         case 'ISO646-CA':
8803                                 return 'CSA_Z243.4-1985-1';
8804         
8805                         case 'CSA7-2':
8806                         case 'CSA_Z243.4-1985-2':
8807                         case 'CSISO122CANADIAN2':
8808                         case 'ISO-IR-122':
8809                         case 'ISO646-CA2':
8810                                 return 'CSA_Z243.4-1985-2';
8811         
8812                         case 'CSA_Z243.4-1985-GR':
8813                         case 'CSISO123CSAZ24341985GR':
8814                         case 'ISO-IR-123':
8815                                 return 'CSA_Z243.4-1985-gr';
8816         
8817                         case 'CSISO139CSN369103':
8818                         case 'CSN_369103':
8819                         case 'ISO-IR-139':
8820                                 return 'CSN_369103';
8821         
8822                         case 'CSDECMCS':
8823                         case 'DEC':
8824                         case 'DEC-MCS':
8825                                 return 'DEC-MCS';
8826         
8827                         case 'CSISO21GERMAN':
8828                         case 'DE':
8829                         case 'DIN_66003':
8830                         case 'ISO-IR-21':
8831                         case 'ISO646-DE':
8832                                 return 'DIN_66003';
8833         
8834                         case 'CSISO646DANISH':
8835                         case 'DK':
8836                         case 'DS2089':
8837                         case 'DS_2089':
8838                         case 'ISO646-DK':
8839                                 return 'DS_2089';
8840         
8841                         case 'CSIBMEBCDICATDE':
8842                         case 'EBCDIC-AT-DE':
8843                                 return 'EBCDIC-AT-DE';
8844         
8845                         case 'CSEBCDICATDEA':
8846                         case 'EBCDIC-AT-DE-A':
8847                                 return 'EBCDIC-AT-DE-A';
8848         
8849                         case 'CSEBCDICCAFR':
8850                         case 'EBCDIC-CA-FR':
8851                                 return 'EBCDIC-CA-FR';
8852         
8853                         case 'CSEBCDICDKNO':
8854                         case 'EBCDIC-DK-NO':
8855                                 return 'EBCDIC-DK-NO';
8856         
8857                         case 'CSEBCDICDKNOA':
8858                         case 'EBCDIC-DK-NO-A':
8859                                 return 'EBCDIC-DK-NO-A';
8860         
8861                         case 'CSEBCDICES':
8862                         case 'EBCDIC-ES':
8863                                 return 'EBCDIC-ES';
8864         
8865                         case 'CSEBCDICESA':
8866                         case 'EBCDIC-ES-A':
8867                                 return 'EBCDIC-ES-A';
8868         
8869                         case 'CSEBCDICESS':
8870                         case 'EBCDIC-ES-S':
8871                                 return 'EBCDIC-ES-S';
8872         
8873                         case 'CSEBCDICFISE':
8874                         case 'EBCDIC-FI-SE':
8875                                 return 'EBCDIC-FI-SE';
8876         
8877                         case 'CSEBCDICFISEA':
8878                         case 'EBCDIC-FI-SE-A':
8879                                 return 'EBCDIC-FI-SE-A';
8880         
8881                         case 'CSEBCDICFR':
8882                         case 'EBCDIC-FR':
8883                                 return 'EBCDIC-FR';
8884         
8885                         case 'CSEBCDICIT':
8886                         case 'EBCDIC-IT':
8887                                 return 'EBCDIC-IT';
8888         
8889                         case 'CSEBCDICPT':
8890                         case 'EBCDIC-PT':
8891                                 return 'EBCDIC-PT';
8892         
8893                         case 'CSEBCDICUK':
8894                         case 'EBCDIC-UK':
8895                                 return 'EBCDIC-UK';
8896         
8897                         case 'CSEBCDICUS':
8898                         case 'EBCDIC-US':
8899                                 return 'EBCDIC-US';
8900         
8901                         case 'CSISO111ECMACYRILLIC':
8902                         case 'ECMA-CYRILLIC':
8903                         case 'ISO-IR-111':
8904                         case 'KOI8-E':
8905                                 return 'ECMA-cyrillic';
8906         
8907                         case 'CSISO17SPANISH':
8908                         case 'ES':
8909                         case 'ISO-IR-17':
8910                         case 'ISO646-ES':
8911                                 return 'ES';
8912         
8913                         case 'CSISO85SPANISH2':
8914                         case 'ES2':
8915                         case 'ISO-IR-85':
8916                         case 'ISO646-ES2':
8917                                 return 'ES2';
8918         
8919                         case 'CSEUCPKDFMTJAPANESE':
8920                         case 'EUC-JP':
8921                         case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
8922                                 return 'EUC-JP';
8923         
8924                         case 'CSEUCKR':
8925                         case 'EUC-KR':
8926                                 return 'EUC-KR';
8927         
8928                         case 'CSEUCFIXWIDJAPANESE':
8929                         case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
8930                                 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
8931         
8932                         case 'GB18030':
8933                                 return 'GB18030';
8934         
8935                         case 'CSGB2312':
8936                         case 'GB2312':
8937                                 return 'GB2312';
8938         
8939                         case 'CP936':
8940                         case 'GBK':
8941                         case 'MS936':
8942                         case 'WINDOWS-936':
8943                                 return 'GBK';
8944         
8945                         case 'CN':
8946                         case 'CSISO57GB1988':
8947                         case 'GB_1988-80':
8948                         case 'ISO-IR-57':
8949                         case 'ISO646-CN':
8950                                 return 'GB_1988-80';
8951         
8952                         case 'CHINESE':
8953                         case 'CSISO58GB231280':
8954                         case 'GB_2312-80':
8955                         case 'ISO-IR-58':
8956                                 return 'GB_2312-80';
8957         
8958                         case 'CSISO153GOST1976874':
8959                         case 'GOST_19768-74':
8960                         case 'ISO-IR-153':
8961                         case 'ST_SEV_358-88':
8962                                 return 'GOST_19768-74';
8963         
8964                         case 'CSHPDESKTOP':
8965                         case 'HP-DESKTOP':
8966                                 return 'HP-DeskTop';
8967         
8968                         case 'CSHPLEGAL':
8969                         case 'HP-LEGAL':
8970                                 return 'HP-Legal';
8971         
8972                         case 'CSHPMATH8':
8973                         case 'HP-MATH8':
8974                                 return 'HP-Math8';
8975         
8976                         case 'CSHPPIFONT':
8977                         case 'HP-PI-FONT':
8978                                 return 'HP-Pi-font';
8979         
8980                         case 'HZ-GB-2312':
8981                                 return 'HZ-GB-2312';
8982         
8983                         case 'CSIBMSYMBOLS':
8984                         case 'IBM-SYMBOLS':
8985                                 return 'IBM-Symbols';
8986         
8987                         case 'CSIBMTHAI':
8988                         case 'IBM-THAI':
8989                                 return 'IBM-Thai';
8990         
8991                         case 'CCSID00858':
8992                         case 'CP00858':
8993                         case 'IBM00858':
8994                         case 'PC-MULTILINGUAL-850+EURO':
8995                                 return 'IBM00858';
8996         
8997                         case 'CCSID00924':
8998                         case 'CP00924':
8999                         case 'EBCDIC-LATIN9--EURO':
9000                         case 'IBM00924':
9001                                 return 'IBM00924';
9002         
9003                         case 'CCSID01140':
9004                         case 'CP01140':
9005                         case 'EBCDIC-US-37+EURO':
9006                         case 'IBM01140':
9007                                 return 'IBM01140';
9008         
9009                         case 'CCSID01141':
9010                         case 'CP01141':
9011                         case 'EBCDIC-DE-273+EURO':
9012                         case 'IBM01141':
9013                                 return 'IBM01141';
9014         
9015                         case 'CCSID01142':
9016                         case 'CP01142':
9017                         case 'EBCDIC-DK-277+EURO':
9018                         case 'EBCDIC-NO-277+EURO':
9019                         case 'IBM01142':
9020                                 return 'IBM01142';
9021         
9022                         case 'CCSID01143':
9023                         case 'CP01143':
9024                         case 'EBCDIC-FI-278+EURO':
9025                         case 'EBCDIC-SE-278+EURO':
9026                         case 'IBM01143':
9027                                 return 'IBM01143';
9028         
9029                         case 'CCSID01144':
9030                         case 'CP01144':
9031                         case 'EBCDIC-IT-280+EURO':
9032                         case 'IBM01144':
9033                                 return 'IBM01144';
9034         
9035                         case 'CCSID01145':
9036                         case 'CP01145':
9037                         case 'EBCDIC-ES-284+EURO':
9038                         case 'IBM01145':
9039                                 return 'IBM01145';
9040         
9041                         case 'CCSID01146':
9042                         case 'CP01146':
9043                         case 'EBCDIC-GB-285+EURO':
9044                         case 'IBM01146':
9045                                 return 'IBM01146';
9046         
9047                         case 'CCSID01147':
9048                         case 'CP01147':
9049                         case 'EBCDIC-FR-297+EURO':
9050                         case 'IBM01147':
9051                                 return 'IBM01147';
9052         
9053                         case 'CCSID01148':
9054                         case 'CP01148':
9055                         case 'EBCDIC-INTERNATIONAL-500+EURO':
9056                         case 'IBM01148':
9057                                 return 'IBM01148';
9058         
9059                         case 'CCSID01149':
9060                         case 'CP01149':
9061                         case 'EBCDIC-IS-871+EURO':
9062                         case 'IBM01149':
9063                                 return 'IBM01149';
9064         
9065                         case 'CP037':
9066                         case 'CSIBM037':
9067                         case 'EBCDIC-CP-CA':
9068                         case 'EBCDIC-CP-NL':
9069                         case 'EBCDIC-CP-US':
9070                         case 'EBCDIC-CP-WT':
9071                         case 'IBM037':
9072                                 return 'IBM037';
9073         
9074                         case 'CP038':
9075                         case 'CSIBM038':
9076                         case 'EBCDIC-INT':
9077                         case 'IBM038':
9078                                 return 'IBM038';
9079         
9080                         case 'CP1026':
9081                         case 'CSIBM1026':
9082                         case 'IBM1026':
9083                                 return 'IBM1026';
9084         
9085                         case 'IBM-1047':
9086                         case 'IBM1047':
9087                                 return 'IBM1047';
9088         
9089                         case 'CP273':
9090                         case 'CSIBM273':
9091                         case 'IBM273':
9092                                 return 'IBM273';
9093         
9094                         case 'CP274':
9095                         case 'CSIBM274':
9096                         case 'EBCDIC-BE':
9097                         case 'IBM274':
9098                                 return 'IBM274';
9099         
9100                         case 'CP275':
9101                         case 'CSIBM275':
9102                         case 'EBCDIC-BR':
9103                         case 'IBM275':
9104                                 return 'IBM275';
9105         
9106                         case 'CSIBM277':
9107                         case 'EBCDIC-CP-DK':
9108                         case 'EBCDIC-CP-NO':
9109                         case 'IBM277':
9110                                 return 'IBM277';
9111         
9112                         case 'CP278':
9113                         case 'CSIBM278':
9114                         case 'EBCDIC-CP-FI':
9115                         case 'EBCDIC-CP-SE':
9116                         case 'IBM278':
9117                                 return 'IBM278';
9118         
9119                         case 'CP280':
9120                         case 'CSIBM280':
9121                         case 'EBCDIC-CP-IT':
9122                         case 'IBM280':
9123                                 return 'IBM280';
9124         
9125                         case 'CP281':
9126                         case 'CSIBM281':
9127                         case 'EBCDIC-JP-E':
9128                         case 'IBM281':
9129                                 return 'IBM281';
9130         
9131                         case 'CP284':
9132                         case 'CSIBM284':
9133                         case 'EBCDIC-CP-ES':
9134                         case 'IBM284':
9135                                 return 'IBM284';
9136         
9137                         case 'CP285':
9138                         case 'CSIBM285':
9139                         case 'EBCDIC-CP-GB':
9140                         case 'IBM285':
9141                                 return 'IBM285';
9142         
9143                         case 'CP290':
9144                         case 'CSIBM290':
9145                         case 'EBCDIC-JP-KANA':
9146                         case 'IBM290':
9147                                 return 'IBM290';
9148         
9149                         case 'CP297':
9150                         case 'CSIBM297':
9151                         case 'EBCDIC-CP-FR':
9152                         case 'IBM297':
9153                                 return 'IBM297';
9154         
9155                         case 'CP420':
9156                         case 'CSIBM420':
9157                         case 'EBCDIC-CP-AR1':
9158                         case 'IBM420':
9159                                 return 'IBM420';
9160         
9161                         case 'CP423':
9162                         case 'CSIBM423':
9163                         case 'EBCDIC-CP-GR':
9164                         case 'IBM423':
9165                                 return 'IBM423';
9166         
9167                         case 'CP424':
9168                         case 'CSIBM424':
9169                         case 'EBCDIC-CP-HE':
9170                         case 'IBM424':
9171                                 return 'IBM424';
9172         
9173                         case '437':
9174                         case 'CP437':
9175                         case 'CSPC8CODEPAGE437':
9176                         case 'IBM437':
9177                                 return 'IBM437';
9178         
9179                         case 'CP500':
9180                         case 'CSIBM500':
9181                         case 'EBCDIC-CP-BE':
9182                         case 'EBCDIC-CP-CH':
9183                         case 'IBM500':
9184                                 return 'IBM500';
9185         
9186                         case 'CP775':
9187                         case 'CSPC775BALTIC':
9188                         case 'IBM775':
9189                                 return 'IBM775';
9190         
9191                         case '850':
9192                         case 'CP850':
9193                         case 'CSPC850MULTILINGUAL':
9194                         case 'IBM850':
9195                                 return 'IBM850';
9196         
9197                         case '851':
9198                         case 'CP851':
9199                         case 'CSIBM851':
9200                         case 'IBM851':
9201                                 return 'IBM851';
9202         
9203                         case '852':
9204                         case 'CP852':
9205                         case 'CSPCP852':
9206                         case 'IBM852':
9207                                 return 'IBM852';
9208         
9209                         case '855':
9210                         case 'CP855':
9211                         case 'CSIBM855':
9212                         case 'IBM855':
9213                                 return 'IBM855';
9214         
9215                         case '857':
9216                         case 'CP857':
9217                         case 'CSIBM857':
9218                         case 'IBM857':
9219                                 return 'IBM857';
9220         
9221                         case '860':
9222                         case 'CP860':
9223                         case 'CSIBM860':
9224                         case 'IBM860':
9225                                 return 'IBM860';
9226         
9227                         case '861':
9228                         case 'CP-IS':
9229                         case 'CP861':
9230                         case 'CSIBM861':
9231                         case 'IBM861':
9232                                 return 'IBM861';
9233         
9234                         case '862':
9235                         case 'CP862':
9236                         case 'CSPC862LATINHEBREW':
9237                         case 'IBM862':
9238                                 return 'IBM862';
9239         
9240                         case '863':
9241                         case 'CP863':
9242                         case 'CSIBM863':
9243                         case 'IBM863':
9244                                 return 'IBM863';
9245         
9246                         case 'CP864':
9247                         case 'CSIBM864':
9248                         case 'IBM864':
9249                                 return 'IBM864';
9250         
9251                         case '865':
9252                         case 'CP865':
9253                         case 'CSIBM865':
9254                         case 'IBM865':
9255                                 return 'IBM865';
9256         
9257                         case '866':
9258                         case 'CP866':
9259                         case 'CSIBM866':
9260                         case 'IBM866':
9261                                 return 'IBM866';
9262         
9263                         case 'CP-AR':
9264                         case 'CP868':
9265                         case 'CSIBM868':
9266                         case 'IBM868':
9267                                 return 'IBM868';
9268         
9269                         case '869':
9270                         case 'CP-GR':
9271                         case 'CP869':
9272                         case 'CSIBM869':
9273                         case 'IBM869':
9274                                 return 'IBM869';
9275         
9276                         case 'CP870':
9277                         case 'CSIBM870':
9278                         case 'EBCDIC-CP-ROECE':
9279                         case 'EBCDIC-CP-YU':
9280                         case 'IBM870':
9281                                 return 'IBM870';
9282         
9283                         case 'CP871':
9284                         case 'CSIBM871':
9285                         case 'EBCDIC-CP-IS':
9286                         case 'IBM871':
9287                                 return 'IBM871';
9288         
9289                         case 'CP880':
9290                         case 'CSIBM880':
9291                         case 'EBCDIC-CYRILLIC':
9292                         case 'IBM880':
9293                                 return 'IBM880';
9294         
9295                         case 'CP891':
9296                         case 'CSIBM891':
9297                         case 'IBM891':
9298                                 return 'IBM891';
9299         
9300                         case 'CP903':
9301                         case 'CSIBM903':
9302                         case 'IBM903':
9303                                 return 'IBM903';
9304         
9305                         case '904':
9306                         case 'CP904':
9307                         case 'CSIBBM904':
9308                         case 'IBM904':
9309                                 return 'IBM904';
9310         
9311                         case 'CP905':
9312                         case 'CSIBM905':
9313                         case 'EBCDIC-CP-TR':
9314                         case 'IBM905':
9315                                 return 'IBM905';
9316         
9317                         case 'CP918':
9318                         case 'CSIBM918':
9319                         case 'EBCDIC-CP-AR2':
9320                         case 'IBM918':
9321                                 return 'IBM918';
9322         
9323                         case 'CSISO143IECP271':
9324                         case 'IEC_P27-1':
9325                         case 'ISO-IR-143':
9326                                 return 'IEC_P27-1';
9327         
9328                         case 'CSISO49INIS':
9329                         case 'INIS':
9330                         case 'ISO-IR-49':
9331                                 return 'INIS';
9332         
9333                         case 'CSISO50INIS8':
9334                         case 'INIS-8':
9335                         case 'ISO-IR-50':
9336                                 return 'INIS-8';
9337         
9338                         case 'CSISO51INISCYRILLIC':
9339                         case 'INIS-CYRILLIC':
9340                         case 'ISO-IR-51':
9341                                 return 'INIS-cyrillic';
9342         
9343                         case 'CSINVARIANT':
9344                         case 'INVARIANT':
9345                                 return 'INVARIANT';
9346         
9347                         case 'ISO-10646-J-1':
9348                                 return 'ISO-10646-J-1';
9349         
9350                         case 'CSUNICODE':
9351                         case 'ISO-10646-UCS-2':
9352                                 return 'ISO-10646-UCS-2';
9353         
9354                         case 'CSUCS4':
9355                         case 'ISO-10646-UCS-4':
9356                                 return 'ISO-10646-UCS-4';
9357         
9358                         case 'CSUNICODEASCII':
9359                         case 'ISO-10646-UCS-BASIC':
9360                                 return 'ISO-10646-UCS-Basic';
9361         
9362                         case 'CSISO10646UTF1':
9363                         case 'ISO-10646-UTF-1':
9364                                 return 'ISO-10646-UTF-1';
9365         
9366                         case 'CSUNICODELATIN1':
9367                         case 'ISO-10646':
9368                         case 'ISO-10646-UNICODE-LATIN1':
9369                                 return 'ISO-10646-Unicode-Latin1';
9370         
9371                         case 'CSISO115481':
9372                         case 'ISO-11548-1':
9373                         case 'ISO_11548-1':
9374                         case 'ISO_TR_11548-1':
9375                                 return 'ISO-11548-1';
9376         
9377                         case 'ISO-2022-CN':
9378                                 return 'ISO-2022-CN';
9379         
9380                         case 'ISO-2022-CN-EXT':
9381                                 return 'ISO-2022-CN-EXT';
9382         
9383                         case 'CSISO2022JP':
9384                         case 'ISO-2022-JP':
9385                                 return 'ISO-2022-JP';
9386         
9387                         case 'CSISO2022JP2':
9388                         case 'ISO-2022-JP-2':
9389                                 return 'ISO-2022-JP-2';
9390         
9391                         case 'CSISO2022KR':
9392                         case 'ISO-2022-KR':
9393                                 return 'ISO-2022-KR';
9394         
9395                         case 'CSWINDOWS30LATIN1':
9396                         case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
9397                                 return 'ISO-8859-1-Windows-3.0-Latin-1';
9398         
9399                         case 'CSWINDOWS31LATIN1':
9400                         case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
9401                                 return 'ISO-8859-1-Windows-3.1-Latin-1';
9402         
9403                         case 'CSISOLATIN6':
9404                         case 'ISO-8859-10':
9405                         case 'ISO-IR-157':
9406                         case 'ISO_8859-10:1992':
9407                         case 'L6':
9408                         case 'LATIN6':
9409                                 return 'ISO-8859-10';
9410         
9411                         case 'ISO-8859-13':
9412                                 return 'ISO-8859-13';
9413         
9414                         case 'ISO-8859-14':
9415                         case 'ISO-CELTIC':
9416                         case 'ISO-IR-199':
9417                         case 'ISO_8859-14':
9418                         case 'ISO_8859-14:1998':
9419                         case 'L8':
9420                         case 'LATIN8':
9421                                 return 'ISO-8859-14';
9422         
9423                         case 'ISO-8859-15':
9424                         case 'ISO_8859-15':
9425                         case 'LATIN-9':
9426                                 return 'ISO-8859-15';
9427         
9428                         case 'ISO-8859-16':
9429                         case 'ISO-IR-226':
9430                         case 'ISO_8859-16':
9431                         case 'ISO_8859-16:2001':
9432                         case 'L10':
9433                         case 'LATIN10':
9434                                 return 'ISO-8859-16';
9435         
9436                         case 'CSISOLATIN2':
9437                         case 'ISO-8859-2':
9438                         case 'ISO-IR-101':
9439                         case 'ISO_8859-2':
9440                         case 'ISO_8859-2:1987':
9441                         case 'L2':
9442                         case 'LATIN2':
9443                                 return 'ISO-8859-2';
9444         
9445                         case 'CSWINDOWS31LATIN2':
9446                         case 'ISO-8859-2-WINDOWS-LATIN-2':
9447                                 return 'ISO-8859-2-Windows-Latin-2';
9448         
9449                         case 'CSISOLATIN3':
9450                         case 'ISO-8859-3':
9451                         case 'ISO-IR-109':
9452                         case 'ISO_8859-3':
9453                         case 'ISO_8859-3:1988':
9454                         case 'L3':
9455                         case 'LATIN3':
9456                                 return 'ISO-8859-3';
9457         
9458                         case 'CSISOLATIN4':
9459                         case 'ISO-8859-4':
9460                         case 'ISO-IR-110':
9461                         case 'ISO_8859-4':
9462                         case 'ISO_8859-4:1988':
9463                         case 'L4':
9464                         case 'LATIN4':
9465                                 return 'ISO-8859-4';
9466         
9467                         case 'CSISOLATINCYRILLIC':
9468                         case 'CYRILLIC':
9469                         case 'ISO-8859-5':
9470                         case 'ISO-IR-144':
9471                         case 'ISO_8859-5':
9472                         case 'ISO_8859-5:1988':
9473                                 return 'ISO-8859-5';
9474         
9475                         case 'ARABIC':
9476                         case 'ASMO-708':
9477                         case 'CSISOLATINARABIC':
9478                         case 'ECMA-114':
9479                         case 'ISO-8859-6':
9480                         case 'ISO-IR-127':
9481                         case 'ISO_8859-6':
9482                         case 'ISO_8859-6:1987':
9483                                 return 'ISO-8859-6';
9484         
9485                         case 'CSISO88596E':
9486                         case 'ISO-8859-6-E':
9487                         case 'ISO_8859-6-E':
9488                                 return 'ISO-8859-6-E';
9489         
9490                         case 'CSISO88596I':
9491                         case 'ISO-8859-6-I':
9492                         case 'ISO_8859-6-I':
9493                                 return 'ISO-8859-6-I';
9494         
9495                         case 'CSISOLATINGREEK':
9496                         case 'ECMA-118':
9497                         case 'ELOT_928':
9498                         case 'GREEK':
9499                         case 'GREEK8':
9500                         case 'ISO-8859-7':
9501                         case 'ISO-IR-126':
9502                         case 'ISO_8859-7':
9503                         case 'ISO_8859-7:1987':
9504                                 return 'ISO-8859-7';
9505         
9506                         case 'CSISOLATINHEBREW':
9507                         case 'HEBREW':
9508                         case 'ISO-8859-8':
9509                         case 'ISO-IR-138':
9510                         case 'ISO_8859-8':
9511                         case 'ISO_8859-8:1988':
9512                                 return 'ISO-8859-8';
9513         
9514                         case 'CSISO88598E':
9515                         case 'ISO-8859-8-E':
9516                         case 'ISO_8859-8-E':
9517                                 return 'ISO-8859-8-E';
9518         
9519                         case 'CSISO88598I':
9520                         case 'ISO-8859-8-I':
9521                         case 'ISO_8859-8-I':
9522                                 return 'ISO-8859-8-I';
9523         
9524                         case 'CSISOLATIN5':
9525                         case 'ISO-8859-9':
9526                         case 'ISO-IR-148':
9527                         case 'ISO_8859-9':
9528                         case 'ISO_8859-9:1989':
9529                         case 'L5':
9530                         case 'LATIN5':
9531                                 return 'ISO-8859-9';
9532         
9533                         case 'CSWINDOWS31LATIN5':
9534                         case 'ISO-8859-9-WINDOWS-LATIN-5':
9535                                 return 'ISO-8859-9-Windows-Latin-5';
9536         
9537                         case 'CSUNICODEIBM1261':
9538                         case 'ISO-UNICODE-IBM-1261':
9539                                 return 'ISO-Unicode-IBM-1261';
9540         
9541                         case 'CSUNICODEIBM1264':
9542                         case 'ISO-UNICODE-IBM-1264':
9543                                 return 'ISO-Unicode-IBM-1264';
9544         
9545                         case 'CSUNICODEIBM1265':
9546                         case 'ISO-UNICODE-IBM-1265':
9547                                 return 'ISO-Unicode-IBM-1265';
9548         
9549                         case 'CSUNICODEIBM1268':
9550                         case 'ISO-UNICODE-IBM-1268':
9551                                 return 'ISO-Unicode-IBM-1268';
9552         
9553                         case 'CSUNICODEIBM1276':
9554                         case 'ISO-UNICODE-IBM-1276':
9555                                 return 'ISO-Unicode-IBM-1276';
9556         
9557                         case 'CSISO10367BOX':
9558                         case 'ISO-IR-155':
9559                         case 'ISO_10367-BOX':
9560                                 return 'ISO_10367-box';
9561         
9562                         case 'CSISO2033':
9563                         case 'E13B':
9564                         case 'ISO-IR-98':
9565                         case 'ISO_2033-1983':
9566                                 return 'ISO_2033-1983';
9567         
9568                         case 'CSISO5427CYRILLIC':
9569                         case 'ISO-IR-37':
9570                         case 'ISO_5427':
9571                                 return 'ISO_5427';
9572         
9573                         case 'ISO-IR-54':
9574                         case 'ISO5427CYRILLIC1981':
9575                         case 'ISO_5427:1981':
9576                                 return 'ISO_5427:1981';
9577         
9578                         case 'CSISO5428GREEK':
9579                         case 'ISO-IR-55':
9580                         case 'ISO_5428:1980':
9581                                 return 'ISO_5428:1980';
9582         
9583                         case 'CSISO646BASIC1983':
9584                         case 'ISO_646.BASIC:1983':
9585                         case 'REF':
9586                                 return 'ISO_646.basic:1983';
9587         
9588                         case 'CSISO2INTLREFVERSION':
9589                         case 'IRV':
9590                         case 'ISO-IR-2':
9591                         case 'ISO_646.IRV:1983':
9592                                 return 'ISO_646.irv:1983';
9593         
9594                         case 'CSISO6937ADD':
9595                         case 'ISO-IR-152':
9596                         case 'ISO_6937-2-25':
9597                                 return 'ISO_6937-2-25';
9598         
9599                         case 'CSISOTEXTCOMM':
9600                         case 'ISO-IR-142':
9601                         case 'ISO_6937-2-ADD':
9602                                 return 'ISO_6937-2-add';
9603         
9604                         case 'CSISO8859SUPP':
9605                         case 'ISO-IR-154':
9606                         case 'ISO_8859-SUPP':
9607                         case 'LATIN1-2-5':
9608                                 return 'ISO_8859-supp';
9609         
9610                         case 'CSISO15ITALIAN':
9611                         case 'ISO-IR-15':
9612                         case 'ISO646-IT':
9613                         case 'IT':
9614                                 return 'IT';
9615         
9616                         case 'CSISO13JISC6220JP':
9617                         case 'ISO-IR-13':
9618                         case 'JIS_C6220-1969':
9619                         case 'JIS_C6220-1969-JP':
9620                         case 'KATAKANA':
9621                         case 'X0201-7':
9622                                 return 'JIS_C6220-1969-jp';
9623         
9624                         case 'CSISO14JISC6220RO':
9625                         case 'ISO-IR-14':
9626                         case 'ISO646-JP':
9627                         case 'JIS_C6220-1969-RO':
9628                         case 'JP':
9629                                 return 'JIS_C6220-1969-ro';
9630         
9631                         case 'CSISO42JISC62261978':
9632                         case 'ISO-IR-42':
9633                         case 'JIS_C6226-1978':
9634                                 return 'JIS_C6226-1978';
9635         
9636                         case 'CSISO87JISX0208':
9637                         case 'ISO-IR-87':
9638                         case 'JIS_C6226-1983':
9639                         case 'JIS_X0208-1983':
9640                         case 'X0208':
9641                                 return 'JIS_C6226-1983';
9642         
9643                         case 'CSISO91JISC62291984A':
9644                         case 'ISO-IR-91':
9645                         case 'JIS_C6229-1984-A':
9646                         case 'JP-OCR-A':
9647                                 return 'JIS_C6229-1984-a';
9648         
9649                         case 'CSISO92JISC62991984B':
9650                         case 'ISO-IR-92':
9651                         case 'ISO646-JP-OCR-B':
9652                         case 'JIS_C6229-1984-B':
9653                         case 'JP-OCR-B':
9654                                 return 'JIS_C6229-1984-b';
9655         
9656                         case 'CSISO93JIS62291984BADD':
9657                         case 'ISO-IR-93':
9658                         case 'JIS_C6229-1984-B-ADD':
9659                         case 'JP-OCR-B-ADD':
9660                                 return 'JIS_C6229-1984-b-add';
9661         
9662                         case 'CSISO94JIS62291984HAND':
9663                         case 'ISO-IR-94':
9664                         case 'JIS_C6229-1984-HAND':
9665                         case 'JP-OCR-HAND':
9666                                 return 'JIS_C6229-1984-hand';
9667         
9668                         case 'CSISO95JIS62291984HANDADD':
9669                         case 'ISO-IR-95':
9670                         case 'JIS_C6229-1984-HAND-ADD':
9671                         case 'JP-OCR-HAND-ADD':
9672                                 return 'JIS_C6229-1984-hand-add';
9673         
9674                         case 'CSISO96JISC62291984KANA':
9675                         case 'ISO-IR-96':
9676                         case 'JIS_C6229-1984-KANA':
9677                                 return 'JIS_C6229-1984-kana';
9678         
9679                         case 'CSJISENCODING':
9680                         case 'JIS_ENCODING':
9681                                 return 'JIS_Encoding';
9682         
9683                         case 'CSHALFWIDTHKATAKANA':
9684                         case 'JIS_X0201':
9685                         case 'X0201':
9686                                 return 'JIS_X0201';
9687         
9688                         case 'CSISO159JISX02121990':
9689                         case 'ISO-IR-159':
9690                         case 'JIS_X0212-1990':
9691                         case 'X0212':
9692                                 return 'JIS_X0212-1990';
9693         
9694                         case 'CSISO141JUSIB1002':
9695                         case 'ISO-IR-141':
9696                         case 'ISO646-YU':
9697                         case 'JS':
9698                         case 'JUS_I.B1.002':
9699                         case 'YU':
9700                                 return 'JUS_I.B1.002';
9701         
9702                         case 'CSISO147MACEDONIAN':
9703                         case 'ISO-IR-147':
9704                         case 'JUS_I.B1.003-MAC':
9705                         case 'MACEDONIAN':
9706                                 return 'JUS_I.B1.003-mac';
9707         
9708                         case 'CSISO146SERBIAN':
9709                         case 'ISO-IR-146':
9710                         case 'JUS_I.B1.003-SERB':
9711                         case 'SERBIAN':
9712                                 return 'JUS_I.B1.003-serb';
9713         
9714                         case 'KOI7-SWITCHED':
9715                                 return 'KOI7-switched';
9716         
9717                         case 'CSKOI8R':
9718                         case 'KOI8-R':
9719                                 return 'KOI8-R';
9720         
9721                         case 'KOI8-U':
9722                                 return 'KOI8-U';
9723         
9724                         case 'CSKSC5636':
9725                         case 'ISO646-KR':
9726                         case 'KSC5636':
9727                                 return 'KSC5636';
9728         
9729                         case 'CSKSC56011987':
9730                         case 'ISO-IR-149':
9731                         case 'KOREAN':
9732                         case 'KSC_5601':
9733                         case 'KS_C_5601-1987':
9734                         case 'KS_C_5601-1989':
9735                                 return 'KS_C_5601-1987';
9736         
9737                         case 'CSKZ1048':
9738                         case 'KZ-1048':
9739                         case 'RK1048':
9740                         case 'STRK1048-2002':
9741                                 return 'KZ-1048';
9742         
9743                         case 'CSISO27LATINGREEK1':
9744                         case 'ISO-IR-27':
9745                         case 'LATIN-GREEK-1':
9746                                 return 'Latin-greek-1';
9747         
9748                         case 'CSMNEM':
9749                         case 'MNEM':
9750                                 return 'MNEM';
9751         
9752                         case 'CSMNEMONIC':
9753                         case 'MNEMONIC':
9754                                 return 'MNEMONIC';
9755         
9756                         case 'CSISO86HUNGARIAN':
9757                         case 'HU':
9758                         case 'ISO-IR-86':
9759                         case 'ISO646-HU':
9760                         case 'MSZ_7795.3':
9761                                 return 'MSZ_7795.3';
9762         
9763                         case 'CSMICROSOFTPUBLISHING':
9764                         case 'MICROSOFT-PUBLISHING':
9765                                 return 'Microsoft-Publishing';
9766         
9767                         case 'CSNATSDANO':
9768                         case 'ISO-IR-9-1':
9769                         case 'NATS-DANO':
9770                                 return 'NATS-DANO';
9771         
9772                         case 'CSNATSDANOADD':
9773                         case 'ISO-IR-9-2':
9774                         case 'NATS-DANO-ADD':
9775                                 return 'NATS-DANO-ADD';
9776         
9777                         case 'CSNATSSEFI':
9778                         case 'ISO-IR-8-1':
9779                         case 'NATS-SEFI':
9780                                 return 'NATS-SEFI';
9781         
9782                         case 'CSNATSSEFIADD':
9783                         case 'ISO-IR-8-2':
9784                         case 'NATS-SEFI-ADD':
9785                                 return 'NATS-SEFI-ADD';
9786         
9787                         case 'CSISO151CUBA':
9788                         case 'CUBA':
9789                         case 'ISO-IR-151':
9790                         case 'ISO646-CU':
9791                         case 'NC_NC00-10:81':
9792                                 return 'NC_NC00-10:81';
9793         
9794                         case 'CSISO69FRENCH':
9795                         case 'FR':
9796                         case 'ISO-IR-69':
9797                         case 'ISO646-FR':
9798                         case 'NF_Z_62-010':
9799                                 return 'NF_Z_62-010';
9800         
9801                         case 'CSISO25FRENCH':
9802                         case 'ISO-IR-25':
9803                         case 'ISO646-FR1':
9804                         case 'NF_Z_62-010_(1973)':
9805                                 return 'NF_Z_62-010_(1973)';
9806         
9807                         case 'CSISO60DANISHNORWEGIAN':
9808                         case 'CSISO60NORWEGIAN1':
9809                         case 'ISO-IR-60':
9810                         case 'ISO646-NO':
9811                         case 'NO':
9812                         case 'NS_4551-1':
9813                                 return 'NS_4551-1';
9814         
9815                         case 'CSISO61NORWEGIAN2':
9816                         case 'ISO-IR-61':
9817                         case 'ISO646-NO2':
9818                         case 'NO2':
9819                         case 'NS_4551-2':
9820                                 return 'NS_4551-2';
9821         
9822                         case 'OSD_EBCDIC_DF03_IRV':
9823                                 return 'OSD_EBCDIC_DF03_IRV';
9824         
9825                         case 'OSD_EBCDIC_DF04_1':
9826                                 return 'OSD_EBCDIC_DF04_1';
9827         
9828                         case 'OSD_EBCDIC_DF04_15':
9829                                 return 'OSD_EBCDIC_DF04_15';
9830         
9831                         case 'CSPC8DANISHNORWEGIAN':
9832                         case 'PC8-DANISH-NORWEGIAN':
9833                                 return 'PC8-Danish-Norwegian';
9834         
9835                         case 'CSPC8TURKISH':
9836                         case 'PC8-TURKISH':
9837                                 return 'PC8-Turkish';
9838         
9839                         case 'CSISO16PORTUGUESE':
9840                         case 'ISO-IR-16':
9841                         case 'ISO646-PT':
9842                         case 'PT':
9843                                 return 'PT';
9844         
9845                         case 'CSISO84PORTUGUESE2':
9846                         case 'ISO-IR-84':
9847                         case 'ISO646-PT2':
9848                         case 'PT2':
9849                                 return 'PT2';
9850         
9851                         case 'CP154':
9852                         case 'CSPTCP154':
9853                         case 'CYRILLIC-ASIAN':
9854                         case 'PT154':
9855                         case 'PTCP154':
9856                                 return 'PTCP154';
9857         
9858                         case 'SCSU':
9859                                 return 'SCSU';
9860         
9861                         case 'CSISO10SWEDISH':
9862                         case 'FI':
9863                         case 'ISO-IR-10':
9864                         case 'ISO646-FI':
9865                         case 'ISO646-SE':
9866                         case 'SE':
9867                         case 'SEN_850200_B':
9868                                 return 'SEN_850200_B';
9869         
9870                         case 'CSISO11SWEDISHFORNAMES':
9871                         case 'ISO-IR-11':
9872                         case 'ISO646-SE2':
9873                         case 'SE2':
9874                         case 'SEN_850200_C':
9875                                 return 'SEN_850200_C';
9876         
9877                         case 'CSSHIFTJIS':
9878                         case 'MS_KANJI':
9879                         case 'SHIFT_JIS':
9880                                 return 'Shift_JIS';
9881         
9882                         case 'CSISO128T101G2':
9883                         case 'ISO-IR-128':
9884                         case 'T.101-G2':
9885                                 return 'T.101-G2';
9886         
9887                         case 'CSISO102T617BIT':
9888                         case 'ISO-IR-102':
9889                         case 'T.61-7BIT':
9890                                 return 'T.61-7bit';
9891         
9892                         case 'CSISO103T618BIT':
9893                         case 'ISO-IR-103':
9894                         case 'T.61':
9895                         case 'T.61-8BIT':
9896                                 return 'T.61-8bit';
9897         
9898                         case 'CSTSCII':
9899                         case 'TSCII':
9900                                 return 'TSCII';
9901         
9902                         case 'CSUNICODE11':
9903                         case 'UNICODE-1-1':
9904                                 return 'UNICODE-1-1';
9905         
9906                         case 'CSUNICODE11UTF7':
9907                         case 'UNICODE-1-1-UTF-7':
9908                                 return 'UNICODE-1-1-UTF-7';
9909         
9910                         case 'CSUNKNOWN8BIT':
9911                         case 'UNKNOWN-8BIT':
9912                                 return 'UNKNOWN-8BIT';
9913         
9914                         case 'ANSI':
9915                         case 'ANSI_X3.4-1968':
9916                         case 'ANSI_X3.4-1986':
9917                         case 'ASCII':
9918                         case 'CP367':
9919                         case 'CSASCII':
9920                         case 'IBM367':
9921                         case 'ISO-IR-6':
9922                         case 'ISO646-US':
9923                         case 'ISO_646.IRV:1991':
9924                         case 'US':
9925                         case 'US-ASCII':
9926                                 return 'US-ASCII';
9927         
9928                         case 'UTF-16':
9929                                 return 'UTF-16';
9930         
9931                         case 'UTF-16BE':
9932                                 return 'UTF-16BE';
9933         
9934                         case 'UTF-16LE':
9935                                 return 'UTF-16LE';
9936         
9937                         case 'UTF-32':
9938                                 return 'UTF-32';
9939         
9940                         case 'UTF-32BE':
9941                                 return 'UTF-32BE';
9942         
9943                         case 'UTF-32LE':
9944                                 return 'UTF-32LE';
9945         
9946                         case 'UTF-7':
9947                                 return 'UTF-7';
9948         
9949                         case 'UTF-8':
9950                                 return 'UTF-8';
9951         
9952                         case 'CSVIQR':
9953                         case 'VIQR':
9954                                 return 'VIQR';
9955         
9956                         case 'CSVISCII':
9957                         case 'VISCII':
9958                                 return 'VISCII';
9959         
9960                         case 'CSVENTURAINTERNATIONAL':
9961                         case 'VENTURA-INTERNATIONAL':
9962                                 return 'Ventura-International';
9963         
9964                         case 'CSVENTURAMATH':
9965                         case 'VENTURA-MATH':
9966                                 return 'Ventura-Math';
9967         
9968                         case 'CSVENTURAUS':
9969                         case 'VENTURA-US':
9970                                 return 'Ventura-US';
9971         
9972                         case 'CSWINDOWS31J':
9973                         case 'WINDOWS-31J':
9974                                 return 'Windows-31J';
9975         
9976                         case 'CSDKUS':
9977                         case 'DK-US':
9978                                 return 'dk-us';
9979         
9980                         case 'CSISO150':
9981                         case 'CSISO150GREEKCCITT':
9982                         case 'GREEK-CCITT':
9983                         case 'ISO-IR-150':
9984                                 return 'greek-ccitt';
9985         
9986                         case 'CSISO88GREEK7':
9987                         case 'GREEK7':
9988                         case 'ISO-IR-88':
9989                                 return 'greek7';
9990         
9991                         case 'CSISO18GREEK7OLD':
9992                         case 'GREEK7-OLD':
9993                         case 'ISO-IR-18':
9994                                 return 'greek7-old';
9995         
9996                         case 'CSHPROMAN8':
9997                         case 'HP-ROMAN8':
9998                         case 'R8':
9999                         case 'ROMAN8':
10000                                 return 'hp-roman8';
10001         
10002                         case 'CSISO90':
10003                         case 'ISO-IR-90':
10004                                 return 'iso-ir-90';
10005         
10006                         case 'CSISO19LATINGREEK':
10007                         case 'ISO-IR-19':
10008                         case 'LATIN-GREEK':
10009                                 return 'latin-greek';
10010         
10011                         case 'CSISO158LAP':
10012                         case 'ISO-IR-158':
10013                         case 'LAP':
10014                         case 'LATIN-LAP':
10015                                 return 'latin-lap';
10016         
10017                         case 'CSMACINTOSH':
10018                         case 'MAC':
10019                         case 'MACINTOSH':
10020                                 return 'macintosh';
10021         
10022                         case 'CSUSDK':
10023                         case 'US-DK':
10024                                 return 'us-dk';
10025         
10026                         case 'CSISO70VIDEOTEXSUPP1':
10027                         case 'ISO-IR-70':
10028                         case 'VIDEOTEX-SUPPL':
10029                                 return 'videotex-suppl';
10030         
10031                         case 'WINDOWS-1250':
10032                                 return 'windows-1250';
10033         
10034                         case 'WINDOWS-1251':
10035                                 return 'windows-1251';
10036         
10037                         case 'CP819':
10038                         case 'CSISOLATIN1':
10039                         case 'IBM819':
10040                         case 'ISO-8859-1':
10041                         case 'ISO-IR-100':
10042                         case 'ISO_8859-1':
10043                         case 'ISO_8859-1:1987':
10044                         case 'L1':
10045                         case 'LATIN1':
10046                         case 'WINDOWS-1252':
10047                                 return 'windows-1252';
10048         
10049                         case 'WINDOWS-1253':
10050                                 return 'windows-1253';
10051         
10052                         case 'WINDOWS-1254':
10053                                 return 'windows-1254';
10054         
10055                         case 'WINDOWS-1255':
10056                                 return 'windows-1255';
10057         
10058                         case 'WINDOWS-1256':
10059                                 return 'windows-1256';
10060         
10061                         case 'WINDOWS-1257':
10062                                 return 'windows-1257';
10063         
10064                         case 'WINDOWS-1258':
10065                                 return 'windows-1258';
10066         
10067                         default:
10068                                 return $encoding;
10069                 }
10070         }
10071
10072         function get_curl_version()
10073         {
10074                 if (is_array($curl = curl_version()))
10075                 {
10076                         $curl = $curl['version'];
10077                 }
10078                 elseif (substr($curl, 0, 5) == 'curl/')
10079                 {
10080                         $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10081                 }
10082                 elseif (substr($curl, 0, 8) == 'libcurl/')
10083                 {
10084                         $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10085                 }
10086                 else
10087                 {
10088                         $curl = 0;
10089                 }
10090                 return $curl;
10091         }
10092
10093         function is_subclass_of($class1, $class2)
10094         {
10095                 if (func_num_args() != 2)
10096                 {
10097                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10098                 }
10099                 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10100                 {
10101                         return is_subclass_of($class1, $class2);
10102                 }
10103                 elseif (is_string($class1) && is_string($class2))
10104                 {
10105                         if (class_exists($class1))
10106                         {
10107                                 if (class_exists($class2))
10108                                 {
10109                                         $class2 = strtolower($class2);
10110                                         while ($class1 = strtolower(get_parent_class($class1)))
10111                                         {
10112                                                 if ($class1 == $class2)
10113                                                 {
10114                                                         return true;
10115                                                 }
10116                                         }
10117                                 }
10118                         }
10119                         else
10120                         {
10121                                 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10122                         }
10123                 }
10124                 return false;
10125         }
10126
10127         /**
10128          * Strip HTML comments
10129          *
10130          * @access public
10131          * @param string $data Data to strip comments from
10132          * @return string Comment stripped string
10133          */
10134         function strip_comments($data)
10135         {
10136                 $output = '';
10137                 while (($start = strpos($data, '<!--')) !== false)
10138                 {
10139                         $output .= substr($data, 0, $start);
10140                         if (($end = strpos($data, '-->', $start)) !== false)
10141                         {
10142                                 $data = substr_replace($data, '', 0, $end + 3);
10143                         }
10144                         else
10145                         {
10146                                 $data = '';
10147                         }
10148                 }
10149                 return $output . $data;
10150         }
10151
10152         function parse_date($dt)
10153         {
10154                 $parser = SimplePie_Parse_Date::get();
10155                 return $parser->parse($dt);
10156         }
10157
10158         /**
10159          * Decode HTML entities
10160          *
10161          * @static
10162          * @access public
10163          * @param string $data Input data
10164          * @return string Output data
10165          */
10166         function entities_decode($data)
10167         {
10168                 $decoder = new SimplePie_Decode_HTML_Entities($data);
10169                 return $decoder->parse();
10170         }
10171
10172         /**
10173          * Remove RFC822 comments
10174          *
10175          * @access public
10176          * @param string $data Data to strip comments from
10177          * @return string Comment stripped string
10178          */
10179         function uncomment_rfc822($string)
10180         {
10181                 $string = (string) $string;
10182                 $position = 0;
10183                 $length = strlen($string);
10184                 $depth = 0;
10185                 
10186                 $output = '';
10187                 
10188                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10189                 {
10190                         $output .= substr($string, $position, $pos - $position);
10191                         $position = $pos + 1;
10192                         if ($string[$pos - 1] !== '\\')
10193                         {
10194                                 $depth++;
10195                                 while ($depth && $position < $length)
10196                                 {
10197                                         $position += strcspn($string, '()', $position);
10198                                         if ($string[$position - 1] === '\\')
10199                                         {
10200                                                 $position++;
10201                                                 continue;
10202                                         }
10203                                         elseif (isset($string[$position]))
10204                                         {
10205                                                 switch ($string[$position])
10206                                                 {
10207                                                         case '(':
10208                                                                 $depth++;
10209                                                                 break;
10210                                                         
10211                                                         case ')':
10212                                                                 $depth--;
10213                                                                 break;
10214                                                 }
10215                                                 $position++;
10216                                         }
10217                                         else
10218                                         {
10219                                                 break;
10220                                         }
10221                                 }
10222                         }
10223                         else
10224                         {
10225                                 $output .= '(';
10226                         }
10227                 }
10228                 $output .= substr($string, $position);
10229                 
10230                 return $output;
10231         }
10232
10233         function parse_mime($mime)
10234         {
10235                 if (($pos = strpos($mime, ';')) === false)
10236                 {
10237                         return trim($mime);
10238                 }
10239                 else
10240                 {
10241                         return trim(substr($mime, 0, $pos));
10242                 }
10243         }
10244
10245         function htmlspecialchars_decode($string, $quote_style)
10246         {
10247                 if (function_exists('htmlspecialchars_decode'))
10248                 {
10249                         return htmlspecialchars_decode($string, $quote_style);
10250                 }
10251                 else
10252                 {
10253                         return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10254                 }
10255         }
10256
10257         function atom_03_construct_type($attribs)
10258         {
10259                 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10260                 {
10261                         $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10262                 }
10263                 else
10264                 {
10265                         $mode = SIMPLEPIE_CONSTRUCT_NONE;
10266                 }
10267                 if (isset($attribs['']['type']))
10268                 {
10269                         switch (strtolower(trim($attribs['']['type'])))
10270                         {
10271                                 case 'text':
10272                                 case 'text/plain':
10273                                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10274
10275                                 case 'html':
10276                                 case 'text/html':
10277                                         return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10278
10279                                 case 'xhtml':
10280                                 case 'application/xhtml+xml':
10281                                         return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10282
10283                                 default:
10284                                         return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10285                         }
10286                 }
10287                 else
10288                 {
10289                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10290                 }
10291         }
10292
10293         function atom_10_construct_type($attribs)
10294         {
10295                 if (isset($attribs['']['type']))
10296                 {
10297                         switch (strtolower(trim($attribs['']['type'])))
10298                         {
10299                                 case 'text':
10300                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10301
10302                                 case 'html':
10303                                         return SIMPLEPIE_CONSTRUCT_HTML;
10304
10305                                 case 'xhtml':
10306                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10307
10308                                 default:
10309                                         return SIMPLEPIE_CONSTRUCT_NONE;
10310                         }
10311                 }
10312                 return SIMPLEPIE_CONSTRUCT_TEXT;
10313         }
10314
10315         function atom_10_content_construct_type($attribs)
10316         {
10317                 if (isset($attribs['']['type']))
10318                 {
10319                         $type = strtolower(trim($attribs['']['type']));
10320                         switch ($type)
10321                         {
10322                                 case 'text':
10323                                         return SIMPLEPIE_CONSTRUCT_TEXT;
10324
10325                                 case 'html':
10326                                         return SIMPLEPIE_CONSTRUCT_HTML;
10327
10328                                 case 'xhtml':
10329                                         return SIMPLEPIE_CONSTRUCT_XHTML;
10330                         }
10331                         if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10332                         {
10333                                 return SIMPLEPIE_CONSTRUCT_NONE;
10334                         }
10335                         else
10336                         {
10337                                 return SIMPLEPIE_CONSTRUCT_BASE64;
10338                         }
10339                 }
10340                 else
10341                 {
10342                         return SIMPLEPIE_CONSTRUCT_TEXT;
10343                 }
10344         }
10345
10346         function is_isegment_nz_nc($string)
10347         {
10348                 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);
10349         }
10350
10351         function space_seperated_tokens($string)
10352         {
10353                 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10354                 $string_length = strlen($string);
10355
10356                 $position = strspn($string, $space_characters);
10357                 $tokens = array();
10358
10359                 while ($position < $string_length)
10360                 {
10361                         $len = strcspn($string, $space_characters, $position);
10362                         $tokens[] = substr($string, $position, $len);
10363                         $position += $len;
10364                         $position += strspn($string, $space_characters, $position);
10365                 }
10366
10367                 return $tokens;
10368         }
10369
10370         function array_unique($array)
10371         {
10372                 if (version_compare(PHP_VERSION, '5.2', '>='))
10373                 {
10374                         return array_unique($array);
10375                 }
10376                 else
10377                 {
10378                         $array = (array) $array;
10379                         $new_array = array();
10380                         $new_array_strings = array();
10381                         foreach ($array as $key => $value)
10382                         {
10383                                 if (is_object($value))
10384                                 {
10385                                         if (method_exists($value, '__toString'))
10386                                         {
10387                                                 $cmp = $value->__toString();
10388                                         }
10389                                         else
10390                                         {
10391                                                 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10392                                         }
10393                                 }
10394                                 elseif (is_array($value))
10395                                 {
10396                                         $cmp = (string) reset($value);
10397                                 }
10398                                 else
10399                                 {
10400                                         $cmp = (string) $value;
10401                                 }
10402                                 if (!in_array($cmp, $new_array_strings))
10403                                 {
10404                                         $new_array[$key] = $value;
10405                                         $new_array_strings[] = $cmp;
10406                                 }
10407                         }
10408                         return $new_array;
10409                 }
10410         }
10411
10412         /**
10413          * Converts a unicode codepoint to a UTF-8 character
10414          *
10415          * @static
10416          * @access public
10417          * @param int $codepoint Unicode codepoint
10418          * @return string UTF-8 character
10419          */
10420         function codepoint_to_utf8($codepoint)
10421         {
10422                 static $cache = array();
10423                 $codepoint = (int) $codepoint;
10424                 if (isset($cache[$codepoint]))
10425                 {
10426                         return $cache[$codepoint];
10427                 }
10428                 elseif ($codepoint < 0)
10429                 {
10430                         return $cache[$codepoint] = false;
10431                 }
10432                 else if ($codepoint <= 0x7f)
10433                 {
10434                         return $cache[$codepoint] = chr($codepoint);
10435                 }
10436                 else if ($codepoint <= 0x7ff)
10437                 {
10438                         return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10439                 }
10440                 else if ($codepoint <= 0xffff)
10441                 {
10442                         return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10443                 }
10444                 else if ($codepoint <= 0x10ffff)
10445                 {
10446                         return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10447                 }
10448                 else
10449                 {
10450                         // U+FFFD REPLACEMENT CHARACTER
10451                         return $cache[$codepoint] = "\xEF\xBF\xBD";
10452                 }
10453         }
10454
10455         /**
10456          * Re-implementation of PHP 5's stripos()
10457          *
10458          * Returns the numeric position of the first occurrence of needle in the
10459          * haystack string.
10460          *
10461          * @static
10462          * @access string
10463          * @param object $haystack
10464          * @param string $needle Note that the needle may be a string of one or more
10465          *     characters. If needle is not a string, it is converted to an integer
10466          *     and applied as the ordinal value of a character.
10467          * @param int $offset The optional offset parameter allows you to specify which
10468          *     character in haystack to start searching. The position returned is still
10469          *     relative to the beginning of haystack.
10470          * @return bool If needle is not found, stripos() will return boolean false.
10471          */
10472         function stripos($haystack, $needle, $offset = 0)
10473         {
10474                 if (function_exists('stripos'))
10475                 {
10476                         return stripos($haystack, $needle, $offset);
10477                 }
10478                 else
10479                 {
10480                         if (is_string($needle))
10481                         {
10482                                 $needle = strtolower($needle);
10483                         }
10484                         elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10485                         {
10486                                 $needle = strtolower(chr($needle));
10487                         }
10488                         else
10489                         {
10490                                 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10491                                 return false;
10492                         }
10493         
10494                         return strpos(strtolower($haystack), $needle, $offset);
10495                 }
10496         }
10497
10498         /**
10499          * Similar to parse_str()
10500          *
10501          * Returns an associative array of name/value pairs, where the value is an
10502          * array of values that have used the same name
10503          *
10504          * @static
10505          * @access string
10506          * @param string $str The input string.
10507          * @return array
10508          */
10509         function parse_str($str)
10510         {
10511                 $return = array();
10512                 $str = explode('&', $str);
10513
10514                 foreach ($str as $section)
10515                 {
10516                         if (strpos($section, '=') !== false)
10517                         {
10518                                 list($name, $value) = explode('=', $section, 2);
10519                                 $return[urldecode($name)][] = urldecode($value);
10520                         }
10521                         else
10522                         {
10523                                 $return[urldecode($section)][] = null;
10524                         }
10525                 }
10526
10527                 return $return;
10528         }
10529         
10530         /**
10531          * Detect XML encoding, as per XML 1.0 Appendix F.1
10532          *
10533          * @todo Add support for EBCDIC
10534          * @param string $data XML data
10535          * @return array Possible encodings
10536          */
10537         function xml_encoding($data)
10538         {
10539                 // UTF-32 Big Endian BOM
10540                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10541                 {
10542                         $encoding[] = 'UTF-32BE';
10543                 }
10544                 // UTF-32 Little Endian BOM
10545                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10546                 {
10547                         $encoding[] = 'UTF-32LE';
10548                 }
10549                 // UTF-16 Big Endian BOM
10550                 elseif (substr($data, 0, 2) === "\xFE\xFF")
10551                 {
10552                         $encoding[] = 'UTF-16BE';
10553                 }
10554                 // UTF-16 Little Endian BOM
10555                 elseif (substr($data, 0, 2) === "\xFF\xFE")
10556                 {
10557                         $encoding[] = 'UTF-16LE';
10558                 }
10559                 // UTF-8 BOM
10560                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10561                 {
10562                         $encoding[] = 'UTF-8';
10563                 }
10564                 // UTF-32 Big Endian Without BOM
10565                 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")
10566                 {
10567                         if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10568                         {
10569                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10570                                 if ($parser->parse())
10571                                 {
10572                                         $encoding[] = $parser->encoding;
10573                                 }
10574                         }
10575                         $encoding[] = 'UTF-32BE';
10576                 }
10577                 // UTF-32 Little Endian Without BOM
10578                 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")
10579                 {
10580                         if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10581                         {
10582                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10583                                 if ($parser->parse())
10584                                 {
10585                                         $encoding[] = $parser->encoding;
10586                                 }
10587                         }
10588                         $encoding[] = 'UTF-32LE';
10589                 }
10590                 // UTF-16 Big Endian Without BOM
10591                 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10592                 {
10593                         if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10594                         {
10595                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10596                                 if ($parser->parse())
10597                                 {
10598                                         $encoding[] = $parser->encoding;
10599                                 }
10600                         }
10601                         $encoding[] = 'UTF-16BE';
10602                 }
10603                 // UTF-16 Little Endian Without BOM
10604                 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10605                 {
10606                         if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10607                         {
10608                                 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10609                                 if ($parser->parse())
10610                                 {
10611                                         $encoding[] = $parser->encoding;
10612                                 }
10613                         }
10614                         $encoding[] = 'UTF-16LE';
10615                 }
10616                 // US-ASCII (or superset)
10617                 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10618                 {
10619                         if ($pos = strpos($data, "\x3F\x3E"))
10620                         {
10621                                 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10622                                 if ($parser->parse())
10623                                 {
10624                                         $encoding[] = $parser->encoding;
10625                                 }
10626                         }
10627                         $encoding[] = 'UTF-8';
10628                 }
10629                 // Fallback to UTF-8
10630                 else
10631                 {
10632                         $encoding[] = 'UTF-8';
10633                 }
10634                 return $encoding;
10635         }
10636 }
10637
10638 /**
10639  * Decode HTML Entities
10640  *
10641  * This implements HTML5 as of revision 967 (2007-06-28)
10642  *
10643  * @package SimplePie
10644  */
10645 class SimplePie_Decode_HTML_Entities
10646 {
10647         /**
10648          * Data to be parsed
10649          *
10650          * @access private
10651          * @var string
10652          */
10653         var $data = '';
10654
10655         /**
10656          * Currently consumed bytes
10657          *
10658          * @access private
10659          * @var string
10660          */
10661         var $consumed = '';
10662
10663         /**
10664          * Position of the current byte being parsed
10665          *
10666          * @access private
10667          * @var int
10668          */
10669         var $position = 0;
10670
10671         /**
10672          * Create an instance of the class with the input data
10673          *
10674          * @access public
10675          * @param string $data Input data
10676          */
10677         function SimplePie_Decode_HTML_Entities($data)
10678         {
10679                 $this->data = $data;
10680         }
10681
10682         /**
10683          * Parse the input data
10684          *
10685          * @access public
10686          * @return string Output data
10687          */
10688         function parse()
10689         {
10690                 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
10691                 {
10692                         $this->consume();
10693                         $this->entity();
10694                         $this->consumed = '';
10695                 }
10696                 return $this->data;
10697         }
10698
10699         /**
10700          * Consume the next byte
10701          *
10702          * @access private
10703          * @return mixed The next byte, or false, if there is no more data
10704          */
10705         function consume()
10706         {
10707                 if (isset($this->data[$this->position]))
10708                 {
10709                         $this->consumed .= $this->data[$this->position];
10710                         return $this->data[$this->position++];
10711                 }
10712                 else
10713                 {
10714                         $this->consumed = false;
10715                         return false;
10716                 }
10717         }
10718
10719         /**
10720          * Consume a range of characters
10721          *
10722          * @access private
10723          * @param string $chars Characters to consume
10724          * @return mixed A series of characters that match the range, or false
10725          */
10726         function consume_range($chars)
10727         {
10728                 if ($len = strspn($this->data, $chars, $this->position))
10729                 {
10730                         $data = substr($this->data, $this->position, $len);
10731                         $this->consumed .= $data;
10732                         $this->position += $len;
10733                         return $data;
10734                 }
10735                 else
10736                 {
10737                         $this->consumed = false;
10738                         return false;
10739                 }
10740         }
10741
10742         /**
10743          * Unconsume one byte
10744          *
10745          * @access private
10746          */
10747         function unconsume()
10748         {
10749                 $this->consumed = substr($this->consumed, 0, -1);
10750                 $this->position--;
10751         }
10752
10753         /**
10754          * Decode an entity
10755          *
10756          * @access private
10757          */
10758         function entity()
10759         {
10760                 switch ($this->consume())
10761                 {
10762                         case "\x09":
10763                         case "\x0A":
10764                         case "\x0B":
10765                         case "\x0B":
10766                         case "\x0C":
10767                         case "\x20":
10768                         case "\x3C":
10769                         case "\x26":
10770                         case false:
10771                                 break;
10772
10773                         case "\x23":
10774                                 switch ($this->consume())
10775                                 {
10776                                         case "\x78":
10777                                         case "\x58":
10778                                                 $range = '0123456789ABCDEFabcdef';
10779                                                 $hex = true;
10780                                                 break;
10781
10782                                         default:
10783                                                 $range = '0123456789';
10784                                                 $hex = false;
10785                                                 $this->unconsume();
10786                                                 break;
10787                                 }
10788
10789                                 if ($codepoint = $this->consume_range($range))
10790                                 {
10791                                         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");
10792
10793                                         if ($hex)
10794                                         {
10795                                                 $codepoint = hexdec($codepoint);
10796                                         }
10797                                         else
10798                                         {
10799                                                 $codepoint = intval($codepoint);
10800                                         }
10801
10802                                         if (isset($windows_1252_specials[$codepoint]))
10803                                         {
10804                                                 $replacement = $windows_1252_specials[$codepoint];
10805                                         }
10806                                         else
10807                                         {
10808                                                 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
10809                                         }
10810
10811                                         if ($this->consume() != ';')
10812                                         {
10813                                                 $this->unconsume();
10814                                         }
10815
10816                                         $consumed_length = strlen($this->consumed);
10817                                         $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
10818                                         $this->position += strlen($replacement) - $consumed_length;
10819                                 }
10820                                 break;
10821
10822                         default:
10823                                 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");
10824
10825                                 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
10826                                 {
10827                                         $consumed = substr($this->consumed, 1);
10828                                         if (isset($entities[$consumed]))
10829                                         {
10830                                                 $match = $consumed;
10831                                         }
10832                                 }
10833
10834                                 if ($match !== null)
10835                                 {
10836                                         $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
10837                                         $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
10838                                 }
10839                                 break;
10840                 }
10841         }
10842 }
10843
10844 /**
10845  * Date Parser
10846  *
10847  * @package SimplePie
10848  */
10849 class SimplePie_Parse_Date
10850 {
10851         /**
10852          * Input data
10853          *
10854          * @access protected
10855          * @var string
10856          */
10857         var $date;
10858
10859         /**
10860          * List of days, calendar day name => ordinal day number in the week
10861          *
10862          * @access protected
10863          * @var array
10864          */
10865         var $day = array(
10866                 // English
10867                 'mon' => 1,
10868                 'monday' => 1,
10869                 'tue' => 2,
10870                 'tuesday' => 2,
10871                 'wed' => 3,
10872                 'wednesday' => 3,
10873                 'thu' => 4,
10874                 'thursday' => 4,
10875                 'fri' => 5,
10876                 'friday' => 5,
10877                 'sat' => 6,
10878                 'saturday' => 6,
10879                 'sun' => 7,
10880                 'sunday' => 7,
10881                 // Dutch
10882                 'maandag' => 1,
10883                 'dinsdag' => 2,
10884                 'woensdag' => 3,
10885                 'donderdag' => 4,
10886                 'vrijdag' => 5,
10887                 'zaterdag' => 6,
10888                 'zondag' => 7,
10889                 // French
10890                 'lundi' => 1,
10891                 'mardi' => 2,
10892                 'mercredi' => 3,
10893                 'jeudi' => 4,
10894                 'vendredi' => 5,
10895                 'samedi' => 6,
10896                 'dimanche' => 7,
10897                 // German
10898                 'montag' => 1,
10899                 'dienstag' => 2,
10900                 'mittwoch' => 3,
10901                 'donnerstag' => 4,
10902                 'freitag' => 5,
10903                 'samstag' => 6,
10904                 'sonnabend' => 6,
10905                 'sonntag' => 7,
10906                 // Italian
10907                 'lunedì' => 1,
10908                 'martedì' => 2,
10909                 'mercoledì' => 3,
10910                 'giovedì' => 4,
10911                 'venerdì' => 5,
10912                 'sabato' => 6,
10913                 'domenica' => 7,
10914                 // Spanish
10915                 'lunes' => 1,
10916                 'martes' => 2,
10917                 'miércoles' => 3,
10918                 'jueves' => 4,
10919                 'viernes' => 5,
10920                 'sábado' => 6,
10921                 'domingo' => 7,
10922                 // Finnish
10923                 'maanantai' => 1,
10924                 'tiistai' => 2,
10925                 'keskiviikko' => 3,
10926                 'torstai' => 4,
10927                 'perjantai' => 5,
10928                 'lauantai' => 6,
10929                 'sunnuntai' => 7,
10930                 // Hungarian
10931                 'hétfő' => 1,
10932                 'kedd' => 2,
10933                 'szerda' => 3,
10934                 'csütörtok' => 4,
10935                 'péntek' => 5,
10936                 'szombat' => 6,
10937                 'vasárnap' => 7,
10938                 // Greek
10939                 'Δευ' => 1,
10940                 'Τρι' => 2,
10941                 'Τετ' => 3,
10942                 'Πεμ' => 4,
10943                 'Παρ' => 5,
10944                 'Σαβ' => 6,
10945                 'Κυρ' => 7,
10946         );
10947
10948         /**
10949          * List of months, calendar month name => calendar month number
10950          *
10951          * @access protected
10952          * @var array
10953          */
10954         var $month = array(
10955                 // English
10956                 'jan' => 1,
10957                 'january' => 1,
10958                 'feb' => 2,
10959                 'february' => 2,
10960                 'mar' => 3,
10961                 'march' => 3,
10962                 'apr' => 4,
10963                 'april' => 4,
10964                 'may' => 5,
10965                 // No long form of May
10966                 'jun' => 6,
10967                 'june' => 6,
10968                 'jul' => 7,
10969                 'july' => 7,
10970                 'aug' => 8,
10971                 'august' => 8,
10972                 'sep' => 9,
10973                 'september' => 8,
10974                 'oct' => 10,
10975                 'october' => 10,
10976                 'nov' => 11,
10977                 'november' => 11,
10978                 'dec' => 12,
10979                 'december' => 12,
10980                 // Dutch
10981                 'januari' => 1,
10982                 'februari' => 2,
10983                 'maart' => 3,
10984                 'april' => 4,
10985                 'mei' => 5,
10986                 'juni' => 6,
10987                 'juli' => 7,
10988                 'augustus' => 8,
10989                 'september' => 9,
10990                 'oktober' => 10,
10991                 'november' => 11,
10992                 'december' => 12,
10993                 // French
10994                 'janvier' => 1,
10995                 'février' => 2,
10996                 'mars' => 3,
10997                 'avril' => 4,
10998                 'mai' => 5,
10999                 'juin' => 6,
11000                 'juillet' => 7,
11001                 'août' => 8,
11002                 'septembre' => 9,
11003                 'octobre' => 10,
11004                 'novembre' => 11,
11005                 'décembre' => 12,
11006                 // German
11007                 'januar' => 1,
11008                 'februar' => 2,
11009                 'märz' => 3,
11010                 'april' => 4,
11011                 'mai' => 5,
11012                 'juni' => 6,
11013                 'juli' => 7,
11014                 'august' => 8,
11015                 'september' => 9,
11016                 'oktober' => 10,
11017                 'november' => 11,
11018                 'dezember' => 12,
11019                 // Italian
11020                 'gennaio' => 1,
11021                 'febbraio' => 2,
11022                 'marzo' => 3,
11023                 'aprile' => 4,
11024                 'maggio' => 5,
11025                 'giugno' => 6,
11026                 'luglio' => 7,
11027                 'agosto' => 8,
11028                 'settembre' => 9,
11029                 'ottobre' => 10,
11030                 'novembre' => 11,
11031                 'dicembre' => 12,
11032                 // Spanish
11033                 'enero' => 1,
11034                 'febrero' => 2,
11035                 'marzo' => 3,
11036                 'abril' => 4,
11037                 'mayo' => 5,
11038                 'junio' => 6,
11039                 'julio' => 7,
11040                 'agosto' => 8,
11041                 'septiembre' => 9,
11042                 'setiembre' => 9,
11043                 'octubre' => 10,
11044                 'noviembre' => 11,
11045                 'diciembre' => 12,
11046                 // Finnish
11047                 'tammikuu' => 1,
11048                 'helmikuu' => 2,
11049                 'maaliskuu' => 3,
11050                 'huhtikuu' => 4,
11051                 'toukokuu' => 5,
11052                 'kesäkuu' => 6,
11053                 'heinäkuu' => 7,
11054                 'elokuu' => 8,
11055                 'suuskuu' => 9,
11056                 'lokakuu' => 10,
11057                 'marras' => 11,
11058                 'joulukuu' => 12,
11059                 // Hungarian
11060                 'január' => 1,
11061                 'február' => 2,
11062                 'március' => 3,
11063                 'április' => 4,
11064                 'május' => 5,
11065                 'június' => 6,
11066                 'július' => 7,
11067                 'augusztus' => 8,
11068                 'szeptember' => 9,
11069                 'október' => 10,
11070                 'november' => 11,
11071                 'december' => 12,
11072                 // Greek
11073                 'Ιαν' => 1,
11074                 'Φεβ' => 2,
11075                 'Μάώ' => 3,
11076                 'Μαώ' => 3,
11077                 'Απρ' => 4,
11078                 'Μάι' => 5,
11079                 'Μαϊ' => 5,
11080                 'Μαι' => 5,
11081                 'Ιούν' => 6,
11082                 'Ιον' => 6,
11083                 'Ιούλ' => 7,
11084                 'Ιολ' => 7,
11085                 'Αύγ' => 8,
11086                 'Αυγ' => 8,
11087                 'Σεπ' => 9,
11088                 'Οκτ' => 10,
11089                 'Νοέ' => 11,
11090                 'Δεκ' => 12,
11091         );
11092
11093         /**
11094          * List of timezones, abbreviation => offset from UTC
11095          *
11096          * @access protected
11097          * @var array
11098          */
11099         var $timezone = array(
11100                 'ACDT' => 37800,
11101                 'ACIT' => 28800,
11102                 'ACST' => 34200,
11103                 'ACT' => -18000,
11104                 'ACWDT' => 35100,
11105                 'ACWST' => 31500,
11106                 'AEDT' => 39600,
11107                 'AEST' => 36000,
11108                 'AFT' => 16200,
11109                 'AKDT' => -28800,
11110                 'AKST' => -32400,
11111                 'AMDT' => 18000,
11112                 'AMT' => -14400,
11113                 'ANAST' => 46800,
11114                 'ANAT' => 43200,
11115                 'ART' => -10800,
11116                 'AZOST' => -3600,
11117                 'AZST' => 18000,
11118                 'AZT' => 14400,
11119                 'BIOT' => 21600,
11120                 'BIT' => -43200,
11121                 'BOT' => -14400,
11122                 'BRST' => -7200,
11123                 'BRT' => -10800,
11124                 'BST' => 3600,
11125                 'BTT' => 21600,
11126                 'CAST' => 18000,
11127                 'CAT' => 7200,
11128                 'CCT' => 23400,
11129                 'CDT' => -18000,
11130                 'CEDT' => 7200,
11131                 'CET' => 3600,
11132                 'CGST' => -7200,
11133                 'CGT' => -10800,
11134                 'CHADT' => 49500,
11135                 'CHAST' => 45900,
11136                 'CIST' => -28800,
11137                 'CKT' => -36000,
11138                 'CLDT' => -10800,
11139                 'CLST' => -14400,
11140                 'COT' => -18000,
11141                 'CST' => -21600,
11142                 'CVT' => -3600,
11143                 'CXT' => 25200,
11144                 'DAVT' => 25200,
11145                 'DTAT' => 36000,
11146                 'EADT' => -18000,
11147                 'EAST' => -21600,
11148                 'EAT' => 10800,
11149                 'ECT' => -18000,
11150                 'EDT' => -14400,
11151                 'EEST' => 10800,
11152                 'EET' => 7200,
11153                 'EGT' => -3600,
11154                 'EKST' => 21600,
11155                 'EST' => -18000,
11156                 'FJT' => 43200,
11157                 'FKDT' => -10800,
11158                 'FKST' => -14400,
11159                 'FNT' => -7200,
11160                 'GALT' => -21600,
11161                 'GEDT' => 14400,
11162                 'GEST' => 10800,
11163                 'GFT' => -10800,
11164                 'GILT' => 43200,
11165                 'GIT' => -32400,
11166                 'GST' => 14400,
11167                 'GST' => -7200,
11168                 'GYT' => -14400,
11169                 'HAA' => -10800,
11170                 'HAC' => -18000,
11171                 'HADT' => -32400,
11172                 'HAE' => -14400,
11173                 'HAP' => -25200,
11174                 'HAR' => -21600,
11175                 'HAST' => -36000,
11176                 'HAT' => -9000,
11177                 'HAY' => -28800,
11178                 'HKST' => 28800,
11179                 'HMT' => 18000,
11180                 'HNA' => -14400,
11181                 'HNC' => -21600,
11182                 'HNE' => -18000,
11183                 'HNP' => -28800,
11184                 'HNR' => -25200,
11185                 'HNT' => -12600,
11186                 'HNY' => -32400,
11187                 'IRDT' => 16200,
11188                 'IRKST' => 32400,
11189                 'IRKT' => 28800,
11190                 'IRST' => 12600,
11191                 'JFDT' => -10800,
11192                 'JFST' => -14400,
11193                 'JST' => 32400,
11194                 'KGST' => 21600,
11195                 'KGT' => 18000,
11196                 'KOST' => 39600,
11197                 'KOVST' => 28800,
11198                 'KOVT' => 25200,
11199                 'KRAST' => 28800,
11200                 'KRAT' => 25200,
11201                 'KST' => 32400,
11202                 'LHDT' => 39600,
11203                 'LHST' => 37800,
11204                 'LINT' => 50400,
11205                 'LKT' => 21600,
11206                 'MAGST' => 43200,
11207                 'MAGT' => 39600,
11208                 'MAWT' => 21600,
11209                 'MDT' => -21600,
11210                 'MESZ' => 7200,
11211                 'MEZ' => 3600,
11212                 'MHT' => 43200,
11213                 'MIT' => -34200,
11214                 'MNST' => 32400,
11215                 'MSDT' => 14400,
11216                 'MSST' => 10800,
11217                 'MST' => -25200,
11218                 'MUT' => 14400,
11219                 'MVT' => 18000,
11220                 'MYT' => 28800,
11221                 'NCT' => 39600,
11222                 'NDT' => -9000,
11223                 'NFT' => 41400,
11224                 'NMIT' => 36000,
11225                 'NOVST' => 25200,
11226                 'NOVT' => 21600,
11227                 'NPT' => 20700,
11228                 'NRT' => 43200,
11229                 'NST' => -12600,
11230                 'NUT' => -39600,
11231                 'NZDT' => 46800,
11232                 'NZST' => 43200,
11233                 'OMSST' => 25200,
11234                 'OMST' => 21600,
11235                 'PDT' => -25200,
11236                 'PET' => -18000,
11237                 'PETST' => 46800,
11238                 'PETT' => 43200,
11239                 'PGT' => 36000,
11240                 'PHOT' => 46800,
11241                 'PHT' => 28800,
11242                 'PKT' => 18000,
11243                 'PMDT' => -7200,
11244                 'PMST' => -10800,
11245                 'PONT' => 39600,
11246                 'PST' => -28800,
11247                 'PWT' => 32400,
11248                 'PYST' => -10800,
11249                 'PYT' => -14400,
11250                 'RET' => 14400,
11251                 'ROTT' => -10800,
11252                 'SAMST' => 18000,
11253                 'SAMT' => 14400,
11254                 'SAST' => 7200,
11255                 'SBT' => 39600,
11256                 'SCDT' => 46800,
11257                 'SCST' => 43200,
11258                 'SCT' => 14400,
11259                 'SEST' => 3600,
11260                 'SGT' => 28800,
11261                 'SIT' => 28800,
11262                 'SRT' => -10800,
11263                 'SST' => -39600,
11264                 'SYST' => 10800,
11265                 'SYT' => 7200,
11266                 'TFT' => 18000,
11267                 'THAT' => -36000,
11268                 'TJT' => 18000,
11269                 'TKT' => -36000,
11270                 'TMT' => 18000,
11271                 'TOT' => 46800,
11272                 'TPT' => 32400,
11273                 'TRUT' => 36000,
11274                 'TVT' => 43200,
11275                 'TWT' => 28800,
11276                 'UYST' => -7200,
11277                 'UYT' => -10800,
11278                 'UZT' => 18000,
11279                 'VET' => -14400,
11280                 'VLAST' => 39600,
11281                 'VLAT' => 36000,
11282                 'VOST' => 21600,
11283                 'VUT' => 39600,
11284                 'WAST' => 7200,
11285                 'WAT' => 3600,
11286                 'WDT' => 32400,
11287                 'WEST' => 3600,
11288                 'WFT' => 43200,
11289                 'WIB' => 25200,
11290                 'WIT' => 32400,
11291                 'WITA' => 28800,
11292                 'WKST' => 18000,
11293                 'WST' => 28800,
11294                 'YAKST' => 36000,
11295                 'YAKT' => 32400,
11296                 'YAPT' => 36000,
11297                 'YEKST' => 21600,
11298                 'YEKT' => 18000,
11299         );
11300
11301         /**
11302          * Cached PCRE for SimplePie_Parse_Date::$day
11303          *
11304          * @access protected
11305          * @var string
11306          */
11307         var $day_pcre;
11308
11309         /**
11310          * Cached PCRE for SimplePie_Parse_Date::$month
11311          *
11312          * @access protected
11313          * @var string
11314          */
11315         var $month_pcre;
11316
11317         /**
11318          * Array of user-added callback methods
11319          *
11320          * @access private
11321          * @var array
11322          */
11323         var $built_in = array();
11324
11325         /**
11326          * Array of user-added callback methods
11327          *
11328          * @access private
11329          * @var array
11330          */
11331         var $user = array();
11332
11333         /**
11334          * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11335          * self::month_pcre, and self::built_in
11336          *
11337          * @access private
11338          */
11339         function SimplePie_Parse_Date()
11340         {
11341                 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11342                 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11343                 
11344                 static $cache;
11345                 if (!isset($cache[get_class($this)]))
11346                 {
11347                         if (extension_loaded('Reflection'))
11348                         {
11349                                 $class = new ReflectionClass(get_class($this));
11350                                 $methods = $class->getMethods();
11351                                 $all_methods = array();
11352                                 foreach ($methods as $method)
11353                                 {
11354                                         $all_methods[] = $method->getName();
11355                                 }
11356                         }
11357                         else
11358                         {
11359                                 $all_methods = get_class_methods($this);
11360                         }
11361                 
11362                         foreach ($all_methods as $method)
11363                         {
11364                                 if (strtolower(substr($method, 0, 5)) === 'date_')
11365                                 {
11366                                         $cache[get_class($this)][] = $method;
11367                                 }
11368                         }
11369                 }
11370                 
11371                 foreach ($cache[get_class($this)] as $method)
11372                 {
11373                         $this->built_in[] = $method;
11374                 }
11375         }
11376         
11377         /**
11378          * Get the object
11379          *
11380          * @access public
11381          */
11382         function get()
11383         {
11384                 static $object;
11385                 if (!$object)
11386                 {
11387                         $object = new SimplePie_Parse_Date;
11388                 }
11389                 return $object;
11390         }
11391
11392         /**
11393          * Parse a date
11394          *
11395          * @final
11396          * @access public
11397          * @param string $date Date to parse
11398          * @return int Timestamp corresponding to date string, or false on failure
11399          */
11400         function parse($date)
11401         {
11402                 foreach ($this->user as $method)
11403                 {
11404                         if (($returned = call_user_func($method, $date)) !== false)
11405                         {
11406                                 return $returned;
11407                         }
11408                 }
11409                 
11410                 foreach ($this->built_in as $method)
11411                 {
11412                         if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11413                         {
11414                                 return $returned;
11415                         }
11416                 }
11417
11418                 return false;
11419         }
11420
11421         /**
11422          * Add a callback method to parse a date
11423          *
11424          * @final
11425          * @access public
11426          * @param callback $callback
11427          */
11428         function add_callback($callback)
11429         {
11430                 if (is_callable($callback))
11431                 {
11432                         $this->user[] = $callback;
11433                 }
11434                 else
11435                 {
11436                         trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11437                 }
11438         }
11439
11440         /**
11441          * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11442          * well as allowing any of upper or lower case "T", horizontal tabs, or
11443          * spaces to be used as the time seperator (including more than one))
11444          *
11445          * @access protected
11446          * @return int Timestamp
11447          */
11448         function date_w3cdtf($date)
11449         {
11450                 static $pcre;
11451                 if (!$pcre)
11452                 {
11453                         $year = '([0-9]{4})';
11454                         $month = $day = $hour = $minute = $second = '([0-9]{2})';
11455                         $decimal = '([0-9]*)';
11456                         $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11457                         $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11458                 }
11459                 if (preg_match($pcre, $date, $match))
11460                 {
11461                         /*
11462                         Capturing subpatterns:
11463                         1: Year
11464                         2: Month
11465                         3: Day
11466                         4: Hour
11467                         5: Minute
11468                         6: Second
11469                         7: Decimal fraction of a second
11470                         8: Zulu
11471                         9: Timezone ±
11472                         10: Timezone hours
11473                         11: Timezone minutes
11474                         */
11475
11476                         // Fill in empty matches
11477                         for ($i = count($match); $i <= 3; $i++)
11478                         {
11479                                 $match[$i] = '1';
11480                         }
11481
11482                         for ($i = count($match); $i <= 7; $i++)
11483                         {
11484                                 $match[$i] = '0';
11485                         }
11486
11487                         // Numeric timezone
11488                         if (isset($match[9]) && $match[9] !== '')
11489                         {
11490                                 $timezone = $match[10] * 3600;
11491                                 $timezone += $match[11] * 60;
11492                                 if ($match[9] === '-')
11493                                 {
11494                                         $timezone = 0 - $timezone;
11495                                 }
11496                         }
11497                         else
11498                         {
11499                                 $timezone = 0;
11500                         }
11501
11502                         // Convert the number of seconds to an integer, taking decimals into account
11503                         $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11504
11505                         return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11506                 }
11507                 else
11508                 {
11509                         return false;
11510                 }
11511         }
11512
11513         /**
11514          * Remove RFC822 comments
11515          *
11516          * @access protected
11517          * @param string $data Data to strip comments from
11518          * @return string Comment stripped string
11519          */
11520         function remove_rfc2822_comments($string)
11521         {
11522                 $string = (string) $string;
11523                 $position = 0;
11524                 $length = strlen($string);
11525                 $depth = 0;
11526
11527                 $output = '';
11528
11529                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11530                 {
11531                         $output .= substr($string, $position, $pos - $position);
11532                         $position = $pos + 1;
11533                         if ($string[$pos - 1] !== '\\')
11534                         {
11535                                 $depth++;
11536                                 while ($depth && $position < $length)
11537                                 {
11538                                         $position += strcspn($string, '()', $position);
11539                                         if ($string[$position - 1] === '\\')
11540                                         {
11541                                                 $position++;
11542                                                 continue;
11543                                         }
11544                                         elseif (isset($string[$position]))
11545                                         {
11546                                                 switch ($string[$position])
11547                                                 {
11548                                                         case '(':
11549                                                                 $depth++;
11550                                                                 break;
11551
11552                                                         case ')':
11553                                                                 $depth--;
11554                                                                 break;
11555                                                 }
11556                                                 $position++;
11557                                         }
11558                                         else
11559                                         {
11560                                                 break;
11561                                         }
11562                                 }
11563                         }
11564                         else
11565                         {
11566                                 $output .= '(';
11567                         }
11568                 }
11569                 $output .= substr($string, $position);
11570
11571                 return $output;
11572         }
11573
11574         /**
11575          * Parse RFC2822's date format
11576          *
11577          * @access protected
11578          * @return int Timestamp
11579          */
11580         function date_rfc2822($date)
11581         {
11582                 static $pcre;
11583                 if (!$pcre)
11584                 {
11585                         $wsp = '[\x09\x20]';
11586                         $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11587                         $optional_fws = $fws . '?';
11588                         $day_name = $this->day_pcre;
11589                         $month = $this->month_pcre;
11590                         $day = '([0-9]{1,2})';
11591                         $hour = $minute = $second = '([0-9]{2})';
11592                         $year = '([0-9]{2,4})';
11593                         $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11594                         $character_zone = '([A-Z]{1,5})';
11595                         $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11596                         $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';
11597                 }
11598                 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11599                 {
11600                         /*
11601                         Capturing subpatterns:
11602                         1: Day name
11603                         2: Day
11604                         3: Month
11605                         4: Year
11606                         5: Hour
11607                         6: Minute
11608                         7: Second
11609                         8: Timezone ±
11610                         9: Timezone hours
11611                         10: Timezone minutes
11612                         11: Alphabetic timezone
11613                         */
11614
11615                         // Find the month number
11616                         $month = $this->month[strtolower($match[3])];
11617
11618                         // Numeric timezone
11619                         if ($match[8] !== '')
11620                         {
11621                                 $timezone = $match[9] * 3600;
11622                                 $timezone += $match[10] * 60;
11623                                 if ($match[8] === '-')
11624                                 {
11625                                         $timezone = 0 - $timezone;
11626                                 }
11627                         }
11628                         // Character timezone
11629                         elseif (isset($this->timezone[strtoupper($match[11])]))
11630                         {
11631                                 $timezone = $this->timezone[strtoupper($match[11])];
11632                         }
11633                         // Assume everything else to be -0000
11634                         else
11635                         {
11636                                 $timezone = 0;
11637                         }
11638
11639                         // Deal with 2/3 digit years
11640                         if ($match[4] < 50)
11641                         {
11642                                 $match[4] += 2000;
11643                         }
11644                         elseif ($match[4] < 1000)
11645                         {
11646                                 $match[4] += 1900;
11647                         }
11648                         
11649                         // Second is optional, if it is empty set it to zero
11650                         if ($match[7] !== '')
11651                         {
11652                                 $second = $match[7];
11653                         }
11654                         else
11655                         {
11656                                 $second = 0;
11657                         }
11658
11659                         return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
11660                 }
11661                 else
11662                 {
11663                         return false;
11664                 }
11665         }
11666
11667         /**
11668          * Parse RFC850's date format
11669          *
11670          * @access protected
11671          * @return int Timestamp
11672          */
11673         function date_rfc850($date)
11674         {
11675                 static $pcre;
11676                 if (!$pcre)
11677                 {
11678                         $space = '[\x09\x20]+';
11679                         $day_name = $this->day_pcre;
11680                         $month = $this->month_pcre;
11681                         $day = '([0-9]{1,2})';
11682                         $year = $hour = $minute = $second = '([0-9]{2})';
11683                         $zone = '([A-Z]{1,5})';
11684                         $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
11685                 }
11686                 if (preg_match($pcre, $date, $match))
11687                 {
11688                         /*
11689                         Capturing subpatterns:
11690                         1: Day name
11691                         2: Day
11692                         3: Month
11693                         4: Year
11694                         5: Hour
11695                         6: Minute
11696                         7: Second
11697                         8: Timezone
11698                         */
11699
11700                         // Month
11701                         $month = $this->month[strtolower($match[3])];
11702
11703                         // Character timezone
11704                         if (isset($this->timezone[strtoupper($match[8])]))
11705                         {
11706                                 $timezone = $this->timezone[strtoupper($match[8])];
11707                         }
11708                         // Assume everything else to be -0000
11709                         else
11710                         {
11711                                 $timezone = 0;
11712                         }
11713
11714                         // Deal with 2 digit year
11715                         if ($match[4] < 50)
11716                         {
11717                                 $match[4] += 2000;
11718                         }
11719                         else
11720                         {
11721                                 $match[4] += 1900;
11722                         }
11723
11724                         return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
11725                 }
11726                 else
11727                 {
11728                         return false;
11729                 }
11730         }
11731
11732         /**
11733          * Parse C99's asctime()'s date format
11734          *
11735          * @access protected
11736          * @return int Timestamp
11737          */
11738         function date_asctime($date)
11739         {
11740                 static $pcre;
11741                 if (!$pcre)
11742                 {
11743                         $space = '[\x09\x20]+';
11744                         $wday_name = $this->day_pcre;
11745                         $mon_name = $this->month_pcre;
11746                         $day = '([0-9]{1,2})';
11747                         $hour = $sec = $min = '([0-9]{2})';
11748                         $year = '([0-9]{4})';
11749                         $terminator = '\x0A?\x00?';
11750                         $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
11751                 }
11752                 if (preg_match($pcre, $date, $match))
11753                 {
11754                         /*
11755                         Capturing subpatterns:
11756                         1: Day name
11757                         2: Month
11758                         3: Day
11759                         4: Hour
11760                         5: Minute
11761                         6: Second
11762                         7: Year
11763                         */
11764
11765                         $month = $this->month[strtolower($match[2])];
11766                         return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
11767                 }
11768                 else
11769                 {
11770                         return false;
11771                 }
11772         }
11773
11774         /**
11775          * Parse dates using strtotime()
11776          *
11777          * @access protected
11778          * @return int Timestamp
11779          */
11780         function date_strtotime($date)
11781         {
11782                 $strtotime = strtotime($date);
11783                 if ($strtotime === -1 || $strtotime === false)
11784                 {
11785                         return false;
11786                 }
11787                 else
11788                 {
11789                         return $strtotime;
11790                 }
11791         }
11792 }
11793
11794 /**
11795  * Content-type sniffing
11796  *
11797  * @package SimplePie
11798  */
11799 class SimplePie_Content_Type_Sniffer
11800 {
11801         /**
11802          * File object
11803          *
11804          * @var SimplePie_File
11805          * @access private
11806          */
11807         var $file;
11808         
11809         /**
11810          * Create an instance of the class with the input file
11811          *
11812          * @access public
11813          * @param SimplePie_Content_Type_Sniffer $file Input file
11814          */
11815         function SimplePie_Content_Type_Sniffer($file)
11816         {
11817                 $this->file = $file;
11818         }
11819         
11820         /**
11821          * Get the Content-Type of the specified file
11822          *
11823          * @access public
11824          * @return string Actual Content-Type
11825          */
11826         function get_type()
11827         {
11828                 if (isset($this->file->headers['content-type']))
11829                 {
11830                         if (!isset($this->file->headers['content-encoding'])
11831                                 && ($this->file->headers['content-type'] === 'text/plain'
11832                                         || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
11833                                         || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
11834                         {
11835                                 return $this->text_or_binary();
11836                         }
11837                         
11838                         if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
11839                         { 
11840                                 $official = substr($this->file->headers['content-type'], 0, $pos);
11841                         }
11842                         else
11843                         {
11844                                 $official = $this->file->headers['content-type'];
11845                         }
11846                         $official = strtolower($official);
11847                         
11848                         if ($official === 'unknown/unknown'
11849                                 || $official === 'application/unknown')
11850                         {
11851                                 return $this->unknown();
11852                         }
11853                         elseif (substr($official, -4) === '+xml'
11854                                 || $official === 'text/xml'
11855                                 || $official === 'application/xml')
11856                         {
11857                                 return $official;
11858                         }
11859                         elseif (substr($official, 0, 6) === 'image/')
11860                         {
11861                                 if ($return = $this->image())
11862                                 {
11863                                         return $return;
11864                                 }
11865                                 else
11866                                 {
11867                                         return $official;
11868                                 }
11869                         }
11870                         elseif ($official === 'text/html')
11871                         {
11872                                 return $this->feed_or_html();
11873                         }
11874                         else
11875                         {
11876                                 return $official;
11877                         }
11878                 }
11879                 else
11880                 {
11881                         return $this->unknown();
11882                 }
11883         }
11884         
11885         /**
11886          * Sniff text or binary
11887          *
11888          * @access private
11889          * @return string Actual Content-Type
11890          */
11891         function text_or_binary()
11892         {
11893                 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
11894                         || substr($this->file->body, 0, 2) === "\xFF\xFE"
11895                         || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
11896                         || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
11897                 {
11898                         return 'text/plain';
11899                 }
11900                 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
11901                 {
11902                         return 'application/octect-stream';
11903                 }
11904                 else
11905                 {
11906                         return 'text/plain';
11907                 }
11908         }
11909         
11910         /**
11911          * Sniff unknown
11912          *
11913          * @access private
11914          * @return string Actual Content-Type
11915          */
11916         function unknown()
11917         {
11918                 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
11919                 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
11920                         || strtolower(substr($this->file->body, $ws, 5)) === '<html'
11921                         || strtolower(substr($this->file->body, $ws, 7)) === '<script')
11922                 {
11923                         return 'text/html';
11924                 }
11925                 elseif (substr($this->file->body, 0, 5) === '%PDF-')
11926                 {
11927                         return 'application/pdf';
11928                 }
11929                 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
11930                 {
11931                         return 'application/postscript';
11932                 }
11933                 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
11934                         || substr($this->file->body, 0, 6) === 'GIF89a')
11935                 {
11936                         return 'image/gif';
11937                 }
11938                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11939                 {
11940                         return 'image/png';
11941                 }
11942                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11943                 {
11944                         return 'image/jpeg';
11945                 }
11946                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11947                 {
11948                         return 'image/bmp';
11949                 }
11950                 else
11951                 {
11952                         return $this->text_or_binary();
11953                 }
11954         }
11955         
11956         /**
11957          * Sniff images
11958          *
11959          * @access private
11960          * @return string Actual Content-Type
11961          */
11962         function image()
11963         {
11964                 if (substr($this->file->body, 0, 6) === 'GIF87a'
11965                         || substr($this->file->body, 0, 6) === 'GIF89a')
11966                 {
11967                         return 'image/gif';
11968                 }
11969                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11970                 {
11971                         return 'image/png';
11972                 }
11973                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11974                 {
11975                         return 'image/jpeg';
11976                 }
11977                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11978                 {
11979                         return 'image/bmp';
11980                 }
11981                 else
11982                 {
11983                         return false;
11984                 }
11985         }
11986         
11987         /**
11988          * Sniff HTML
11989          *
11990          * @access private
11991          * @return string Actual Content-Type
11992          */
11993         function feed_or_html()
11994         {
11995                 $len = strlen($this->file->body);
11996                 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
11997                 
11998                 while ($pos < $len)
11999                 {
12000                         switch ($this->file->body[$pos])
12001                         {
12002                                 case "\x09":
12003                                 case "\x0A":
12004                                 case "\x0D":
12005                                 case "\x20":
12006                                         $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12007                                         continue 2;
12008                                 
12009                                 case '<':
12010                                         $pos++;
12011                                         break;
12012                                 
12013                                 default:
12014                                         return 'text/html';
12015                         }
12016                         
12017                         if (substr($this->file->body, $pos, 3) === '!--')
12018                         {
12019                                 $pos += 3;
12020                                 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12021                                 {
12022                                         $pos += 3;
12023                                 }
12024                                 else
12025                                 {
12026                                         return 'text/html';
12027                                 }
12028                         }
12029                         elseif (substr($this->file->body, $pos, 1) === '!')
12030                         {
12031                                 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12032                                 {
12033                                         $pos++;
12034                                 }
12035                                 else
12036                                 {
12037                                         return 'text/html';
12038                                 }
12039                         }
12040                         elseif (substr($this->file->body, $pos, 1) === '?')
12041                         {
12042                                 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12043                                 {
12044                                         $pos += 2;
12045                                 }
12046                                 else
12047                                 {
12048                                         return 'text/html';
12049                                 }
12050                         }
12051                         elseif (substr($this->file->body, $pos, 3) === 'rss'
12052                                 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12053                         {
12054                                 return 'application/rss+xml';
12055                         }
12056                         elseif (substr($this->file->body, $pos, 4) === 'feed')
12057                         {
12058                                 return 'application/atom+xml';
12059                         }
12060                         else
12061                         {
12062                                 return 'text/html';
12063                         }
12064                 }
12065                 
12066                 return 'text/html';
12067         }
12068 }
12069
12070 /**
12071  * Parses the XML Declaration
12072  *
12073  * @package SimplePie
12074  */
12075 class SimplePie_XML_Declaration_Parser
12076 {
12077         /**
12078          * XML Version
12079          *
12080          * @access public
12081          * @var string
12082          */
12083         var $version = '1.0';
12084         
12085         /**
12086          * Encoding
12087          *
12088          * @access public
12089          * @var string
12090          */
12091         var $encoding = 'UTF-8';
12092         
12093         /**
12094          * Standalone
12095          *
12096          * @access public
12097          * @var bool
12098          */
12099         var $standalone = false;
12100
12101         /**
12102          * Current state of the state machine
12103          *
12104          * @access private
12105          * @var string
12106          */
12107         var $state = 'before_version_name';
12108         
12109         /**
12110          * Input data
12111          *
12112          * @access private
12113          * @var string
12114          */
12115         var $data = '';
12116
12117         /**
12118          * Input data length (to avoid calling strlen() everytime this is needed)
12119          *
12120          * @access private
12121          * @var int
12122          */
12123         var $data_length = 0;
12124
12125         /**
12126          * Current position of the pointer
12127          *
12128          * @var int
12129          * @access private
12130          */
12131         var $position = 0;
12132         
12133         /**
12134          * Create an instance of the class with the input data
12135          *
12136          * @access public
12137          * @param string $data Input data
12138          */
12139         function SimplePie_XML_Declaration_Parser($data)
12140         {
12141                 $this->data = $data;
12142                 $this->data_length = strlen($this->data);
12143         }
12144
12145         /**
12146          * Parse the input data
12147          *
12148          * @access public
12149          * @return bool true on success, false on failure
12150          */
12151         function parse()
12152         {
12153                 while ($this->state && $this->state !== 'emit' && $this->has_data())
12154                 {
12155                         $state = $this->state;
12156                         $this->$state();
12157                 }
12158                 $this->data = '';
12159                 if ($this->state === 'emit')
12160                 {
12161                         return true;
12162                 }
12163                 else
12164                 {
12165                         $this->version = '';
12166                         $this->encoding = '';
12167                         $this->standalone = '';
12168                         return false;
12169                 }
12170         }
12171
12172         /**
12173          * Check whether there is data beyond the pointer
12174          *
12175          * @access private
12176          * @return bool true if there is further data, false if not
12177          */
12178         function has_data()
12179         {
12180                 return (bool) ($this->position < $this->data_length);
12181         }
12182         
12183         /**
12184          * Advance past any whitespace
12185          *
12186          * @return int Number of whitespace characters passed
12187          */
12188         function skip_whitespace()
12189         {
12190                 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12191                 $this->position += $whitespace;
12192                 return $whitespace;
12193         }
12194         
12195         /**
12196          * Read value
12197          */
12198         function get_value()
12199         {
12200                 $quote = substr($this->data, $this->position, 1);
12201                 if ($quote === '"' || $quote === "'")
12202                 {
12203                         $this->position++;
12204                         $len = strcspn($this->data, $quote, $this->position);
12205                         if ($this->has_data())
12206                         {
12207                                 $value = substr($this->data, $this->position, $len);
12208                                 $this->position += $len + 1;
12209                                 return $value;
12210                         }
12211                 }
12212                 return false;
12213         }
12214         
12215         function before_version_name()
12216         {
12217                 if ($this->skip_whitespace())
12218                 {
12219                         $this->state = 'version_name';
12220                 }
12221                 else
12222                 {
12223                         $this->state = false;
12224                 }
12225         }
12226         
12227         function version_name()
12228         {
12229                 if (substr($this->data, $this->position, 7) === 'version')
12230                 {
12231                         $this->position += 7;
12232                         $this->skip_whitespace();
12233                         $this->state = 'version_equals';
12234                 }
12235                 else
12236                 {
12237                         $this->state = false;
12238                 }
12239         }
12240         
12241         function version_equals()
12242         {
12243                 if (substr($this->data, $this->position, 1) === '=')
12244                 {
12245                         $this->position++;
12246                         $this->skip_whitespace();
12247                         $this->state = 'version_value';
12248                 }
12249                 else
12250                 {
12251                         $this->state = false;
12252                 }
12253         }
12254         
12255         function version_value()
12256         {
12257                 if ($this->version = $this->get_value())
12258                 {
12259                         $this->skip_whitespace();
12260                         if ($this->has_data())
12261                         {
12262                                 $this->state = 'encoding_name';
12263                         }
12264                         else
12265                         {
12266                                 $this->state = 'emit';
12267                         }
12268                 }
12269                 else
12270                 {
12271                         $this->state = 'standalone_name';
12272                 }
12273         }
12274         
12275         function encoding_name()
12276         {
12277                 if (substr($this->data, $this->position, 8) === 'encoding')
12278                 {
12279                         $this->position += 8;
12280                         $this->skip_whitespace();
12281                         $this->state = 'encoding_equals';
12282                 }
12283                 else
12284                 {
12285                         $this->state = false;
12286                 }
12287         }
12288         
12289         function encoding_equals()
12290         {
12291                 if (substr($this->data, $this->position, 1) === '=')
12292                 {
12293                         $this->position++;
12294                         $this->skip_whitespace();
12295                         $this->state = 'encoding_value';
12296                 }
12297                 else
12298                 {
12299                         $this->state = false;
12300                 }
12301         }
12302         
12303         function encoding_value()
12304         {
12305                 if ($this->encoding = $this->get_value())
12306                 {
12307                         $this->skip_whitespace();
12308                         if ($this->has_data())
12309                         {
12310                                 $this->state = 'standalone_name';
12311                         }
12312                         else
12313                         {
12314                                 $this->state = 'emit';
12315                         }
12316                 }
12317                 else
12318                 {
12319                         $this->state = false;
12320                 }
12321         }
12322         
12323         function standalone_name()
12324         {
12325                 if (substr($this->data, $this->position, 10) === 'standalone')
12326                 {
12327                         $this->position += 10;
12328                         $this->skip_whitespace();
12329                         $this->state = 'standalone_equals';
12330                 }
12331                 else
12332                 {
12333                         $this->state = false;
12334                 }
12335         }
12336         
12337         function standalone_equals()
12338         {
12339                 if (substr($this->data, $this->position, 1) === '=')
12340                 {
12341                         $this->position++;
12342                         $this->skip_whitespace();
12343                         $this->state = 'standalone_value';
12344                 }
12345                 else
12346                 {
12347                         $this->state = false;
12348                 }
12349         }
12350         
12351         function standalone_value()
12352         {
12353                 if ($standalone = $this->get_value())
12354                 {
12355                         switch ($standalone)
12356                         {
12357                                 case 'yes':
12358                                         $this->standalone = true;
12359                                         break;
12360                                 
12361                                 case 'no':
12362                                         $this->standalone = false;
12363                                         break;
12364                                 
12365                                 default:
12366                                         $this->state = false;
12367                                         return;
12368                         }
12369                         
12370                         $this->skip_whitespace();
12371                         if ($this->has_data())
12372                         {
12373                                 $this->state = false;
12374                         }
12375                         else
12376                         {
12377                                 $this->state = 'emit';
12378                         }
12379                 }
12380                 else
12381                 {
12382                         $this->state = false;
12383                 }
12384         }
12385 }
12386
12387 class SimplePie_Locator
12388 {
12389         var $useragent;
12390         var $timeout;
12391         var $file;
12392         var $local = array();
12393         var $elsewhere = array();
12394         var $file_class = 'SimplePie_File';
12395         var $cached_entities = array();
12396         var $http_base;
12397         var $base;
12398         var $base_location = 0;
12399         var $checked_feeds = 0;
12400         var $max_checked_feeds = 10;
12401         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12402
12403         function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12404         {
12405                 $this->file =& $file;
12406                 $this->file_class = $file_class;
12407                 $this->useragent = $useragent;
12408                 $this->timeout = $timeout;
12409                 $this->max_checked_feeds = $max_checked_feeds;
12410                 $this->content_type_sniffer_class;
12411         }
12412
12413         function find($type = SIMPLEPIE_LOCATOR_ALL)
12414         {
12415                 if ($this->is_feed($this->file))
12416                 {
12417                         return $this->file;
12418                 }
12419                 
12420                 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12421                 {
12422                         $sniffer = new $this->content_type_sniffer_class($this->file);
12423                         if ($sniffer->get_type() !== 'text/html')
12424                         {
12425                                 return null;
12426                         }
12427                 }
12428
12429                 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12430                 {
12431                         $this->get_base();
12432                 }
12433
12434                 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12435                 {
12436                         return $working;
12437                 }
12438
12439                 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12440                 {
12441                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12442                         {
12443                                 return $working;
12444                         }
12445
12446                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12447                         {
12448                                 return $working;
12449                         }
12450
12451                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12452                         {
12453                                 return $working;
12454                         }
12455
12456                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12457                         {
12458                                 return $working;
12459                         }
12460                 }
12461                 return null;
12462         }
12463
12464         function is_feed(&$file)
12465         {
12466                 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12467                 {
12468                         $sniffer = new $this->content_type_sniffer_class($file);
12469                         $sniffed = $sniffer->get_type();
12470                         if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
12471                         {
12472                                 return true;
12473                         }
12474                         else
12475                         {
12476                                 return false;
12477                         }
12478                 }
12479                 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12480                 {
12481                         return true;
12482                 }
12483                 else
12484                 {
12485                         return false;
12486                 }
12487         }
12488
12489         function get_base()
12490         {
12491                 $this->http_base = $this->file->url;
12492                 $this->base = $this->http_base;
12493                 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12494                 foreach ($elements as $element)
12495                 {
12496                         if ($element['attribs']['href']['data'] !== '')
12497                         {
12498                                 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12499                                 $this->base_location = $element['offset'];
12500                                 break;
12501                         }
12502                 }
12503         }
12504
12505         function autodiscovery()
12506         {
12507                 $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));
12508                 $done = array();
12509                 foreach ($links as $link)
12510                 {
12511                         if ($this->checked_feeds == $this->max_checked_feeds)
12512                         {
12513                                 break;
12514                         }
12515                         if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12516                         {
12517                                 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12518
12519                                 if ($this->base_location < $link['offset'])
12520                                 {
12521                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12522                                 }
12523                                 else
12524                                 {
12525                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12526                                 }
12527
12528                                 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'))))
12529                                 {
12530                                         $this->checked_feeds++;
12531                                         $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12532                                         if ($this->is_feed($feed))
12533                                         {
12534                                                 return $feed;
12535                                         }
12536                                 }
12537                                 $done[] = $href;
12538                         }
12539                 }
12540                 return null;
12541         }
12542
12543         function get_links()
12544         {
12545                 $links = SimplePie_Misc::get_element('a', $this->file->body);
12546                 foreach ($links as $link)
12547                 {
12548                         if (isset($link['attribs']['href']['data']))
12549                         {
12550                                 $href = trim($link['attribs']['href']['data']);
12551                                 $parsed = SimplePie_Misc::parse_url($href);
12552                                 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12553                                 {
12554                                         if ($this->base_location < $link['offset'])
12555                                         {
12556                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12557                                         }
12558                                         else
12559                                         {
12560                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12561                                         }
12562
12563                                         $current = SimplePie_Misc::parse_url($this->file->url);
12564
12565                                         if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12566                                         {
12567                                                 $this->local[] = $href;
12568                                         }
12569                                         else
12570                                         {
12571                                                 $this->elsewhere[] = $href;
12572                                         }
12573                                 }
12574                         }
12575                 }
12576                 $this->local = array_unique($this->local);
12577                 $this->elsewhere = array_unique($this->elsewhere);
12578                 if (!empty($this->local) || !empty($this->elsewhere))
12579                 {
12580                         return true;
12581                 }
12582                 return null;
12583         }
12584
12585         function extension(&$array)
12586         {
12587                 foreach ($array as $key => $value)
12588                 {
12589                         if ($this->checked_feeds == $this->max_checked_feeds)
12590                         {
12591                                 break;
12592                         }
12593                         if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12594                         {
12595                                 $this->checked_feeds++;
12596                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12597                                 if ($this->is_feed($feed))
12598                                 {
12599                                         return $feed;
12600                                 }
12601                                 else
12602                                 {
12603                                         unset($array[$key]);
12604                                 }
12605                         }
12606                 }
12607                 return null;
12608         }
12609
12610         function body(&$array)
12611         {
12612                 foreach ($array as $key => $value)
12613                 {
12614                         if ($this->checked_feeds == $this->max_checked_feeds)
12615                         {
12616                                 break;
12617                         }
12618                         if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12619                         {
12620                                 $this->checked_feeds++;
12621                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12622                                 if ($this->is_feed($feed))
12623                                 {
12624                                         return $feed;
12625                                 }
12626                                 else
12627                                 {
12628                                         unset($array[$key]);
12629                                 }
12630                         }
12631                 }
12632                 return null;
12633         }
12634 }
12635
12636 class SimplePie_Parser
12637 {
12638         var $error_code;
12639         var $error_string;
12640         var $current_line;
12641         var $current_column;
12642         var $current_byte;
12643         var $separator = ' ';
12644         var $feed = false;
12645         var $namespace = array('');
12646         var $element = array('');
12647         var $xml_base = array('');
12648         var $xml_base_explicit = array(false);
12649         var $xml_lang = array('');
12650         var $data = array();
12651         var $datas = array(array());
12652         var $current_xhtml_construct = -1;
12653         var $encoding;
12654
12655         function parse(&$data, $encoding)
12656         {
12657                 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
12658                 if (strtoupper($encoding) == 'US-ASCII')
12659                 {
12660                         $this->encoding = 'UTF-8';
12661                 }
12662                 else
12663                 {
12664                         $this->encoding = $encoding;
12665                 }
12666
12667                 // Strip BOM:
12668                 // UTF-32 Big Endian BOM
12669                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
12670                 {
12671                         $data = substr($data, 4);
12672                 }
12673                 // UTF-32 Little Endian BOM
12674                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
12675                 {
12676                         $data = substr($data, 4);
12677                 }
12678                 // UTF-16 Big Endian BOM
12679                 elseif (substr($data, 0, 2) === "\xFE\xFF")
12680                 {
12681                         $data = substr($data, 2);
12682                 }
12683                 // UTF-16 Little Endian BOM
12684                 elseif (substr($data, 0, 2) === "\xFF\xFE")
12685                 {
12686                         $data = substr($data, 2);
12687                 }
12688                 // UTF-8 BOM
12689                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
12690                 {
12691                         $data = substr($data, 3);
12692                 }
12693                 
12694                 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
12695                 {
12696                         $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
12697                         if ($declaration->parse())
12698                         {
12699                                 $data = substr($data, $pos + 2);
12700                                 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
12701                         }
12702                         else
12703                         {
12704                                 $this->error_string = 'SimplePie bug! Please report this!';
12705                                 return false;
12706                         }
12707                 }
12708                 
12709                 $return = true;
12710
12711                 // Create the parser
12712                 $xml = xml_parser_create_ns($this->encoding, $this->separator);
12713                 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
12714                 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
12715                 xml_set_object($xml, $this);
12716                 xml_set_character_data_handler($xml, 'cdata');
12717                 xml_set_element_handler($xml, 'tag_open', 'tag_close');
12718
12719                 // Parse!
12720                 if (!xml_parse($xml, $data, true))
12721                 {
12722                         $this->error_code = xml_get_error_code($xml);
12723                         $this->error_string = xml_error_string($this->error_code);
12724                         $return = false;
12725                 }
12726                 $this->current_line = xml_get_current_line_number($xml);
12727                 $this->current_column = xml_get_current_column_number($xml);
12728                 $this->current_byte = xml_get_current_byte_index($xml);
12729                 xml_parser_free($xml);
12730                 return $return;
12731         }
12732
12733         function get_error_code()
12734         {
12735                 return $this->error_code;
12736         }
12737
12738         function get_error_string()
12739         {
12740                 return $this->error_string;
12741         }
12742
12743         function get_current_line()
12744         {
12745                 return $this->current_line;
12746         }
12747
12748         function get_current_column()
12749         {
12750                 return $this->current_column;
12751         }
12752
12753         function get_current_byte()
12754         {
12755                 return $this->current_byte;
12756         }
12757
12758         function get_data()
12759         {
12760                 return $this->data;
12761         }
12762
12763         function tag_open($parser, $tag, $attributes)
12764         {
12765                 if ($this->feed === 0)
12766                 {
12767                         return;
12768                 }
12769                 elseif ($this->feed == false)
12770                 {
12771                         if (in_array($tag, array(
12772                                 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
12773                                 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
12774                                 'rss',
12775                                 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
12776                         )))
12777                         {
12778                                         $this->feed = 1;
12779                         }
12780                 }
12781                 else
12782                 {
12783                         $this->feed++;
12784                 }
12785
12786                 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
12787
12788                 $attribs = array();
12789                 foreach ($attributes as $name => $value)
12790                 {
12791                         list($attrib_namespace, $attribute) = $this->split_ns($name);
12792                         $attribs[$attrib_namespace][$attribute] = $value;
12793                 }
12794
12795                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
12796                 {
12797                         $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
12798                         $this->xml_base_explicit[] = true;
12799                 }
12800                 else
12801                 {
12802                         $this->xml_base[] = end($this->xml_base);
12803                         $this->xml_base_explicit[] = end($this->xml_base_explicit);
12804                 }
12805
12806                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
12807                 {
12808                         $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
12809                 }
12810                 else
12811                 {
12812                         $this->xml_lang[] = end($this->xml_lang);
12813                 }
12814
12815                 if ($this->current_xhtml_construct >= 0)
12816                 {
12817                         $this->current_xhtml_construct++;
12818                         if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
12819                         {
12820                                 $this->data['data'] .= '<' . end($this->element);
12821                                 if (isset($attribs['']))
12822                                 {
12823                                         foreach ($attribs[''] as $name => $value)
12824                                         {
12825                                                 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
12826                                         }
12827                                 }
12828                                 $this->data['data'] .= '>';
12829                         }
12830                 }
12831                 else
12832                 {
12833                         $this->datas[] =& $this->data;
12834                         $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
12835                         $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));
12836                         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')
12837                         || (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'))
12838                         {
12839                                 $this->current_xhtml_construct = 0;
12840                         }
12841                 }
12842         }
12843
12844         function cdata($parser, $cdata)
12845         {
12846                 if ($this->current_xhtml_construct >= 0)
12847                 {
12848                         $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
12849                 }
12850                 elseif ($this->feed > 1)
12851                 {
12852                         $this->data['data'] .= $cdata;
12853                 }
12854         }
12855
12856         function tag_close($parser, $tag)
12857         {
12858                 if (!$this->feed)
12859                 {
12860                         return;
12861                 }
12862
12863                 if ($this->current_xhtml_construct >= 0)
12864                 {
12865                         $this->current_xhtml_construct--;
12866                         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')))
12867                         {
12868                                 $this->data['data'] .= '</' . end($this->element) . '>';
12869                         }
12870                 }
12871                 if ($this->current_xhtml_construct == -1)
12872                 {
12873                         $this->data =& $this->datas[$this->feed];
12874                         array_pop($this->datas);
12875                 }
12876
12877                 array_pop($this->element);
12878                 array_pop($this->namespace);
12879                 array_pop($this->xml_base);
12880                 array_pop($this->xml_base_explicit);
12881                 array_pop($this->xml_lang);
12882                 $this->feed--;
12883         }
12884
12885         function split_ns($string)
12886         {
12887                 static $cache = array();
12888                 if (!isset($cache[$string]))
12889                 {
12890                         if ($pos = strpos($string, $this->separator))
12891                         {
12892                                 static $separator_length;
12893                                 if (!$separator_length)
12894                                 {
12895                                         $separator_length = strlen($this->separator);
12896                                 }
12897                                 $namespace = substr($string, 0, $pos);
12898                                 $local_name = substr($string, $pos + $separator_length);
12899                                 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
12900                                 {
12901                                         $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
12902                                 }
12903                                 $cache[$string] = array($namespace, $local_name);
12904                         }
12905                         else
12906                         {
12907                                 $cache[$string] = array('', $string);
12908                         }
12909                 }
12910                 return $cache[$string];
12911         }
12912 }
12913
12914 /**
12915  * @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 shortern a string while preserving HTML tags
12916  */
12917 class SimplePie_Sanitize
12918 {
12919         // Private vars
12920         var $base;
12921
12922         // Options
12923         var $remove_div = true;
12924         var $image_handler = '';
12925         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
12926         var $encode_instead_of_strip = false;
12927         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
12928         var $strip_comments = false;
12929         var $output_encoding = 'UTF-8';
12930         var $enable_cache = true;
12931         var $cache_location = './cache';
12932         var $cache_name_function = 'md5';
12933         var $cache_class = 'SimplePie_Cache';
12934         var $file_class = 'SimplePie_File';
12935         var $timeout = 10;
12936         var $useragent = '';
12937         var $force_fsockopen = false;
12938
12939         var $replace_url_attributes = array(
12940                 'a' => 'href',
12941                 'area' => 'href',
12942                 'blockquote' => 'cite',
12943                 'del' => 'cite',
12944                 'form' => 'action',
12945                 'img' => array('longdesc', 'src'),
12946                 'input' => 'src',
12947                 'ins' => 'cite',
12948                 'q' => 'cite'
12949         );
12950
12951         function remove_div($enable = true)
12952         {
12953                 $this->remove_div = (bool) $enable;
12954         }
12955
12956         function set_image_handler($page = false)
12957         {
12958                 if ($page)
12959                 {
12960                         $this->image_handler = (string) $page;
12961                 }
12962                 else
12963                 {
12964                         $this->image_handler = false;
12965                 }
12966         }
12967
12968         function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
12969         {
12970                 if (isset($enable_cache))
12971                 {
12972                         $this->enable_cache = (bool) $enable_cache;
12973                 }
12974
12975                 if ($cache_location)
12976                 {
12977                         $this->cache_location = (string) $cache_location;
12978                 }
12979
12980                 if ($cache_name_function)
12981                 {
12982                         $this->cache_name_function = (string) $cache_name_function;
12983                 }
12984
12985                 if ($cache_class)
12986                 {
12987                         $this->cache_class = (string) $cache_class;
12988                 }
12989         }
12990
12991         function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
12992         {
12993                 if ($file_class)
12994                 {
12995                         $this->file_class = (string) $file_class;
12996                 }
12997
12998                 if ($timeout)
12999                 {
13000                         $this->timeout = (string) $timeout;
13001                 }
13002
13003                 if ($useragent)
13004                 {
13005                         $this->useragent = (string) $useragent;
13006                 }
13007
13008                 if ($force_fsockopen)
13009                 {
13010                         $this->force_fsockopen = (string) $force_fsockopen;
13011                 }
13012         }
13013
13014         function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13015         {
13016                 if ($tags)
13017                 {
13018                         if (is_array($tags))
13019                         {
13020                                 $this->strip_htmltags = $tags;
13021                         }
13022                         else
13023                         {
13024                                 $this->strip_htmltags = explode(',', $tags);
13025                         }
13026                 }
13027                 else
13028                 {
13029                         $this->strip_htmltags = false;
13030                 }
13031         }
13032
13033         function encode_instead_of_strip($encode = false)
13034         {
13035                 $this->encode_instead_of_strip = (bool) $encode;
13036         }
13037
13038         function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13039         {
13040                 if ($attribs)
13041                 {
13042                         if (is_array($attribs))
13043                         {
13044                                 $this->strip_attributes = $attribs;
13045                         }
13046                         else
13047                         {
13048                                 $this->strip_attributes = explode(',', $attribs);
13049                         }
13050                 }
13051                 else
13052                 {
13053                         $this->strip_attributes = false;
13054                 }
13055         }
13056
13057         function strip_comments($strip = false)
13058         {
13059                 $this->strip_comments = (bool) $strip;
13060         }
13061
13062         function set_output_encoding($encoding = 'UTF-8')
13063         {
13064                 $this->output_encoding = (string) $encoding;
13065         }
13066
13067         /**
13068          * Set element/attribute key/value pairs of HTML attributes
13069          * containing URLs that need to be resolved relative to the feed
13070          *
13071          * @access public
13072          * @since 1.0
13073          * @param array $element_attribute Element/attribute key/value pairs
13074          */
13075         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'))
13076         {
13077                 $this->replace_url_attributes = (array) $element_attribute;
13078         }
13079
13080         function sanitize($data, $type, $base = '')
13081         {
13082                 $data = trim($data);
13083                 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13084                 {
13085                         if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13086                         {
13087                                 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))
13088                                 {
13089                                         $type |= SIMPLEPIE_CONSTRUCT_HTML;
13090                                 }
13091                                 else
13092                                 {
13093                                         $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13094                                 }
13095                         }
13096
13097                         if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13098                         {
13099                                 $data = base64_decode($data);
13100                         }
13101
13102                         if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13103                         {
13104                                 if ($this->remove_div)
13105                                 {
13106                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13107                                         $data = preg_replace('/<\/div>$/', '', $data);
13108                                 }
13109                                 else
13110                                 {
13111                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13112                                 }
13113                         }
13114
13115                         if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13116                         {
13117                                 // Strip comments
13118                                 if ($this->strip_comments)
13119                                 {
13120                                         $data = SimplePie_Misc::strip_comments($data);
13121                                 }
13122
13123                                 // Strip out HTML tags and attributes that might cause various security problems.
13124                                 // Based on recommendations by Mark Pilgrim at:
13125                                 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13126                                 if ($this->strip_htmltags)
13127                                 {
13128                                         foreach ($this->strip_htmltags as $tag)
13129                                         {
13130                                                 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13131                                                 while (preg_match($pcre, $data))
13132                                                 {
13133                                                         $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13134                                                 }
13135                                         }
13136                                 }
13137
13138                                 if ($this->strip_attributes)
13139                                 {
13140                                         foreach ($this->strip_attributes as $attrib)
13141                                         {
13142                                                 $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);
13143                                         }
13144                                 }
13145
13146                                 // Replace relative URLs
13147                                 $this->base = $base;
13148                                 foreach ($this->replace_url_attributes as $element => $attributes)
13149                                 {
13150                                         $data = $this->replace_urls($data, $element, $attributes);
13151                                 }
13152
13153                                 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13154                                 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13155                                 {
13156                                         $images = SimplePie_Misc::get_element('img', $data);
13157                                         foreach ($images as $img)
13158                                         {
13159                                                 if (isset($img['attribs']['src']['data']))
13160                                                 {
13161                                                         $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13162                                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13163
13164                                                         if ($cache->load())
13165                                                         {
13166                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13167                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13168                                                         }
13169                                                         else
13170                                                         {
13171                                                                 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13172                                                                 $headers = $file->headers;
13173
13174                                                                 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13175                                                                 {
13176                                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13177                                                                         {
13178                                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13179                                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13180                                                                         }
13181                                                                         else
13182                                                                         {
13183                                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13184                                                                         }
13185                                                                 }
13186                                                         }
13187                                                 }
13188                                         }
13189                                 }
13190
13191                                 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13192                                 $data = trim($data);
13193                         }
13194
13195                         if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13196                         {
13197                                 $data = SimplePie_Misc::absolutize_url($data, $base);
13198                         }
13199
13200                         if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13201                         {
13202                                 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13203                         }
13204
13205                         if ($this->output_encoding != 'UTF-8')
13206                         {
13207                                 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13208                         }
13209                 }
13210                 return $data;
13211         }
13212
13213         function replace_urls($data, $tag, $attributes)
13214         {
13215                 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13216                 {
13217                         $elements = SimplePie_Misc::get_element($tag, $data);
13218                         foreach ($elements as $element)
13219                         {
13220                                 if (is_array($attributes))
13221                                 {
13222                                         foreach ($attributes as $attribute)
13223                                         {
13224                                                 if (isset($element['attribs'][$attribute]['data']))
13225                                                 {
13226                                                         $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13227                                                         $new_element = SimplePie_Misc::element_implode($element);
13228                                                         $data = str_replace($element['full'], $new_element, $data);
13229                                                         $element['full'] = $new_element;
13230                                                 }
13231                                         }
13232                                 }
13233                                 elseif (isset($element['attribs'][$attributes]['data']))
13234                                 {
13235                                         $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13236                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13237                                 }
13238                         }
13239                 }
13240                 return $data;
13241         }
13242
13243         function do_strip_htmltags($match)
13244         {
13245                 if ($this->encode_instead_of_strip)
13246                 {
13247                         if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13248                         {
13249                                 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13250                                 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13251                                 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
13252                         }
13253                         else
13254                         {
13255                                 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13256                         }
13257                 }
13258                 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13259                 {
13260                         return $match[4];
13261                 }
13262                 else
13263                 {
13264                         return '';
13265                 }
13266         }
13267 }
13268
13269 ?>