ここの情報は古いです。ご理解頂いた上でお取り扱いください。

source: OpenPNE/trunk/lib/include/simplepie.inc @ 4851

Last change on this file since 4851 was 4851, checked in by ebihara, 15 years ago

#1710:SimplePieライブラリのバージョンを1.0b3.2から1.0.1に上げた

File size: 279.4 KB
Line 
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 "Razzleberry"
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 */
49define('SIMPLEPIE_NAME', 'SimplePie');
50
51/**
52 * SimplePie Version
53 */
54define('SIMPLEPIE_VERSION', '1.0.1');
55
56/**
57 * SimplePie Build
58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
59 */
60define('SIMPLEPIE_BUILD', 20070719221955);
61
62/**
63 * SimplePie Website URL
64 */
65define('SIMPLEPIE_URL', 'http://simplepie.org/');
66
67/**
68 * SimplePie Useragent
69 * @see SimplePie::set_useragent()
70 */
71define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
72
73/**
74 * SimplePie Linkback
75 */
76define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
77
78/**
79 * No Autodiscovery
80 * @see SimplePie::set_autodiscovery_level()
81 */
82define('SIMPLEPIE_LOCATOR_NONE', 0);
83
84/**
85 * Feed Link Element Autodiscovery
86 * @see SimplePie::set_autodiscovery_level()
87 */
88define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
89
90/**
91 * Local Feed Extension Autodiscovery
92 * @see SimplePie::set_autodiscovery_level()
93 */
94define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
95
96/**
97 * Local Feed Body Autodiscovery
98 * @see SimplePie::set_autodiscovery_level()
99 */
100define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
101
102/**
103 * Remote Feed Extension Autodiscovery
104 * @see SimplePie::set_autodiscovery_level()
105 */
106define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
107
108/**
109 * Remote Feed Body Autodiscovery
110 * @see SimplePie::set_autodiscovery_level()
111 */
112define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
113
114/**
115 * All Feed Autodiscovery
116 * @see SimplePie::set_autodiscovery_level()
117 */
118define('SIMPLEPIE_LOCATOR_ALL', 31);
119
120/**
121 * No known feed type
122 */
123define('SIMPLEPIE_TYPE_NONE', 0);
124
125/**
126 * RSS 0.90
127 */
128define('SIMPLEPIE_TYPE_RSS_090', 1);
129
130/**
131 * RSS 0.91 (Netscape)
132 */
133define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
134
135/**
136 * RSS 0.91 (Userland)
137 */
138define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
139
140/**
141 * RSS 0.91 (both Netscape and Userland)
142 */
143define('SIMPLEPIE_TYPE_RSS_091', 6);
144
145/**
146 * RSS 0.92
147 */
148define('SIMPLEPIE_TYPE_RSS_092', 8);
149
150/**
151 * RSS 0.93
152 */
153define('SIMPLEPIE_TYPE_RSS_093', 16);
154
155/**
156 * RSS 0.94
157 */
158define('SIMPLEPIE_TYPE_RSS_094', 32);
159
160/**
161 * RSS 1.0
162 */
163define('SIMPLEPIE_TYPE_RSS_10', 64);
164
165/**
166 * RSS 2.0
167 */
168define('SIMPLEPIE_TYPE_RSS_20', 128);
169
170/**
171 * RDF-based RSS
172 */
173define('SIMPLEPIE_TYPE_RSS_RDF', 65);
174
175/**
176 * Non-RDF-based RSS (truly intended as syndication format)
177 */
178define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
179
180/**
181 * All RSS
182 */
183define('SIMPLEPIE_TYPE_RSS_ALL', 255);
184
185/**
186 * Atom 0.3
187 */
188define('SIMPLEPIE_TYPE_ATOM_03', 256);
189
190/**
191 * Atom 1.0
192 */
193define('SIMPLEPIE_TYPE_ATOM_10', 512);
194
195/**
196 * All Atom
197 */
198define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
199
200/**
201 * All feed types
202 */
203define('SIMPLEPIE_TYPE_ALL', 1023);
204
205/**
206 * No construct
207 */
208define('SIMPLEPIE_CONSTRUCT_NONE', 0);
209
210/**
211 * Text construct
212 */
213define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
214
215/**
216 * HTML construct
217 */
218define('SIMPLEPIE_CONSTRUCT_HTML', 2);
219
220/**
221 * XHTML construct
222 */
223define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
224
225/**
226 * base64-encoded construct
227 */
228define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
229
230/**
231 * IRI construct
232 */
233define('SIMPLEPIE_CONSTRUCT_IRI', 16);
234
235/**
236 * A construct that might be HTML
237 */
238define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
239
240/**
241 * All constructs
242 */
243define('SIMPLEPIE_CONSTRUCT_ALL', 63);
244
245/**
246 * PCRE for HTML attributes
247 */
248define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[a-z0-9\-._:]*)))?)*)\s*');
249
250/**
251 * PCRE for XML attributes
252 */
253define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
254
255/**
256 * XML Namespace
257 */
258define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
259
260/**
261 * Atom 1.0 Namespace
262 */
263define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
264
265/**
266 * Atom 0.3 Namespace
267 */
268define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
269
270/**
271 * RDF Namespace
272 */
273define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
274
275/**
276 * RSS 0.90 Namespace
277 */
278define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
279
280/**
281 * RSS 1.0 Namespace
282 */
283define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
284
285/**
286 * RSS 1.0 Content Module Namespace
287 */
288define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
289
290/**
291 * DC 1.0 Namespace
292 */
293define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
294
295/**
296 * DC 1.1 Namespace
297 */
298define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
299
300/**
301 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
302 */
303define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
304
305/**
306 * GeoRSS Namespace
307 */
308define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
309
310/**
311 * Media RSS Namespace
312 */
313define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
314
315/**
316 * iTunes RSS Namespace
317 */
318define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
319
320/**
321 * XHTML Namespace
322 */
323define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
324
325/**
326 * IANA Link Relations Registry
327 */
328define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
329
330/**
331 * Whether we're running on PHP5
332 */
333define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
334
335/**
336 * SimplePie
337 *
338 * @package SimplePie
339 * @version "Razzleberry"
340 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
341 * @author Ryan Parman
342 * @author Geoffrey Sneddon
343 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
344 */
345class SimplePie
346{
347        /**
348         * @var array Raw data
349         * @access private
350         */
351        var $data = array();
352
353        /**
354         * @var mixed Error string
355         * @access private
356         */
357        var $error;
358
359        /**
360         * @var object Instance of SimplePie_Sanitize (or other class)
361         * @see SimplePie::set_sanitize_class()
362         * @access private
363         */
364        var $sanitize;
365
366        /**
367         * @var string SimplePie Useragent
368         * @see SimplePie::set_useragent()
369         * @access private
370         */
371        var $useragent = SIMPLEPIE_USERAGENT;
372
373        /**
374         * @var string Feed URL
375         * @see SimplePie::set_feed_url()
376         * @access private
377         */
378        var $feed_url;
379
380        /**
381         * @var object Instance of SimplePie_File to use as a feed
382         * @see SimplePie::set_file()
383         * @access private
384         */
385        var $file;
386
387        /**
388         * @var string Raw feed data
389         * @see SimplePie::set_raw_data()
390         * @access private
391         */
392        var $raw_data;
393
394        /**
395         * @var int Timeout for fetching remote files
396         * @see SimplePie::set_timeout()
397         * @access private
398         */
399        var $timeout = 10;
400
401        /**
402         * @var bool Forces fsockopen() to be used for remote files instead
403         * of cURL, even if a new enough version is installed
404         * @see SimplePie::force_fsockopen()
405         * @access private
406         */
407        var $force_fsockopen = false;
408
409        /**
410         * @var bool Enable/Disable XML dump
411         * @see SimplePie::enable_xml_dump()
412         * @access private
413         */
414        var $xml_dump = false;
415
416        /**
417         * @var bool Enable/Disable Caching
418         * @see SimplePie::enable_cache()
419         * @access private
420         */
421        var $cache = true;
422
423        /**
424         * @var int Cache duration (in seconds)
425         * @see SimplePie::set_cache_duration()
426         * @access private
427         */
428        var $cache_duration = 3600;
429
430        /**
431         * @var int Auto-discovery cache duration (in seconds)
432         * @see SimplePie::set_autodiscovery_cache_duration()
433         * @access private
434         */
435        var $autodiscovery_cache_duration = 604800; // 7 Days.
436
437        /**
438         * @var string Cache location (relative to executing script)
439         * @see SimplePie::set_cache_location()
440         * @access private
441         */
442        var $cache_location = './cache';
443
444        /**
445         * @var string Function that creates the cache filename
446         * @see SimplePie::set_cache_name_function()
447         * @access private
448         */
449        var $cache_name_function = 'md5';
450
451        /**
452         * @var bool Reorder feed by date descending
453         * @see SimplePie::enable_order_by_date()
454         * @access private
455         */
456        var $order_by_date = true;
457
458        /**
459         * @var mixed Force input encoding to be set to the follow value
460         * (false, or anything type-cast to false, disables this feature)
461         * @see SimplePie::set_input_encoding()
462         * @access private
463         */
464        var $input_encoding = false;
465
466        /**
467         * @var int Feed Autodiscovery Level
468         * @see SimplePie::set_autodiscovery_level()
469         * @access private
470         */
471        var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
472
473        /**
474         * @var string Class used for caching feeds
475         * @see SimplePie::set_cache_class()
476         * @access private
477         */
478        var $cache_class = 'SimplePie_Cache';
479
480        /**
481         * @var string Class used for locating feeds
482         * @see SimplePie::set_locator_class()
483         * @access private
484         */
485        var $locator_class = 'SimplePie_Locator';
486
487        /**
488         * @var string Class used for parsing feeds
489         * @see SimplePie::set_parser_class()
490         * @access private
491         */
492        var $parser_class = 'SimplePie_Parser';
493
494        /**
495         * @var string Class used for fetching feeds
496         * @see SimplePie::set_file_class()
497         * @access private
498         */
499        var $file_class = 'SimplePie_File';
500
501        /**
502         * @var string Class used for items
503         * @see SimplePie::set_item_class()
504         * @access private
505         */
506        var $item_class = 'SimplePie_Item';
507
508        /**
509         * @var string Class used for authors
510         * @see SimplePie::set_author_class()
511         * @access private
512         */
513        var $author_class = 'SimplePie_Author';
514
515        /**
516         * @var string Class used for categories
517         * @see SimplePie::set_category_class()
518         * @access private
519         */
520        var $category_class = 'SimplePie_Category';
521
522        /**
523         * @var string Class used for enclosures
524         * @see SimplePie::set_enclosures_class()
525         * @access private
526         */
527        var $enclosure_class = 'SimplePie_Enclosure';
528
529        /**
530         * @var string Class used for Media RSS <media:text> captions
531         * @see SimplePie::set_caption_class()
532         * @access private
533         */
534        var $caption_class = 'SimplePie_Caption';
535
536        /**
537         * @var string Class used for Media RSS <media:copyright>
538         * @see SimplePie::set_copyright_class()
539         * @access private
540         */
541        var $copyright_class = 'SimplePie_Copyright';
542
543        /**
544         * @var string Class used for Media RSS <media:credit>
545         * @see SimplePie::set_credit_class()
546         * @access private
547         */
548        var $credit_class = 'SimplePie_Credit';
549
550        /**
551         * @var string Class used for Media RSS <media:rating>
552         * @see SimplePie::set_rating_class()
553         * @access private
554         */
555        var $rating_class = 'SimplePie_Rating';
556
557        /**
558         * @var string Class used for Media RSS <media:restriction>
559         * @see SimplePie::set_restriction_class()
560         * @access private
561         */
562        var $restriction_class = 'SimplePie_Restriction';
563
564        /**
565         * @var mixed Set javascript query string parameter (false, or
566         * anything type-cast to false, disables this feature)
567         * @see SimplePie::set_javascript()
568         * @access private
569         */
570        var $javascript = 'js';
571
572        /**
573         * @var int Maximum number of feeds to check with autodiscovery
574         * @see SimplePie::set_max_checked_feeds()
575         * @access private
576         */
577        var $max_checked_feeds = 10;
578
579        /**
580         * @var string Web-accessible path to the handler_favicon.php file.
581         * @see SimplePie::set_favicon_handler()
582         * @access private
583         */
584        var $favicon_handler = '';
585
586        /**
587         * @var string Web-accessible path to the handler_image.php file.
588         * @see SimplePie::set_image_handler()
589         * @access private
590         */
591        var $image_handler = '';
592
593        /**
594         * @var array Stores the URLs when multiple feeds are being initialized.
595         * @see SimplePie::set_feed_url()
596         * @access private
597         */
598        var $multifeed_url = array();
599
600        /**
601         * @var array Stores SimplePie objects when multiple feeds initialized.
602         * @access private
603         */
604        var $multifeed_objects = array();
605
606        /**
607         * @var array Stores the get_object_vars() array for use with multifeeds.
608         * @see SimplePie::set_feed_url()
609         * @access private
610         */
611        var $config_settings = null;
612
613        /**
614         * @var array Stores the default attributes to be stripped by strip_attributes().
615         * @see SimplePie::strip_attributes()
616         * @access private
617         */
618        var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
619
620        /**
621         * @var array Stores the default tags to be stripped by strip_htmltags().
622         * @see SimplePie::strip_htmltags()
623         * @access private
624         */
625        var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
626
627        /**
628         * The SimplePie class contains feed level data and options
629         *
630         * There are two ways that you can create a new SimplePie object. The first
631         * is by passing a feed URL as a parameter to the SimplePie constructor
632         * (as well as optionally setting the cache location and cache expiry). This
633         * will initialise the whole feed with all of the default settings, and you
634         * can begin accessing methods and properties immediately.
635         *
636         * The second way is to create the SimplePie object with no parameters
637         * at all. This will enable you to set configuration options. After setting
638         * them, you must initialise the feed using $feed->init(). At that point the
639         * object's methods and properties will be available to you. This format is
640         * what is used throughout this documentation.
641         *
642         * @access public
643         * @since 1.0 Preview Release
644         * @param string $feed_url This is the URL you want to parse.
645         * @param string $cache_location This is where you want the cache to be stored.
646         * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
647         */
648        function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
649        {
650                // Other objects, instances created here so we can set options on them
651                $this->sanitize =& new SimplePie_Sanitize;
652
653                // Set options if they're passed to the constructor
654                if ($cache_location !== null)
655                {
656                        $this->set_cache_location($cache_location);
657                }
658
659                if ($cache_duration !== null)
660                {
661                        $this->set_cache_duration($cache_duration);
662                }
663
664                // Only init the script if we're passed a feed URL
665                if ($feed_url !== null)
666                {
667                        $this->set_feed_url($feed_url);
668                        $this->init();
669                }
670        }
671
672        /**
673         * Used for converting object to a string
674         */
675        function __toString()
676        {
677                return md5(serialize($this->data));
678        }
679
680        /**
681         * This is the URL of the feed you want to parse.
682         *
683         * This allows you to enter the URL of the feed you want to parse, or the
684         * website you want to try to use auto-discovery on. This takes priority
685         * over any set raw data.
686         *
687         * You can set multiple feeds to mash together by passing an array instead
688         * of a string for the $url. Remember that with each additional feed comes
689         * additional processing and resources.
690         *
691         * @access public
692         * @since 1.0 Preview Release
693         * @param mixed $url This is the URL (or array of URLs) that you want to parse.
694         * @see SimplePie::set_raw_data()
695         */
696        function set_feed_url($url)
697        {
698                if (is_array($url))
699                {
700                        $this->multifeed_url = array();
701                        foreach ($url as $value)
702                        {
703                                $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
704                        }
705                }
706                else
707                {
708                        $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
709                }
710        }
711
712        /**
713         * Provides an instance of SimplePie_File to use as a feed
714         *
715         * @access public
716         * @param object &$file Instance of SimplePie_File (or subclass)
717         * @return bool True on success, false on failure
718         */
719        function set_file(&$file)
720        {
721                if (SimplePie_Misc::is_a($file, 'SimplePie_File'))
722                {
723                        $this->feed_url = $file->url;
724                        $this->file =& $file;
725                        return true;
726                }
727                return false;
728        }
729
730        /**
731         * Allows you to use a string of RSS/Atom data instead of a remote feed.
732         *
733         * If you have a feed available as a string in PHP, you can tell SimplePie
734         * to parse that data string instead of a remote feed. Any set feed URL
735         * takes precedence.
736         *
737         * @access public
738         * @since 1.0 Beta 3
739         * @param string $data RSS or Atom data as a string.
740         * @see SimplePie::set_feed_url()
741         */
742        function set_raw_data($data)
743        {
744                $this->raw_data = trim($data);
745        }
746
747        /**
748         * Allows you to override the default timeout for fetching remote feeds.
749         *
750         * This allows you to change the maximum time the feed's server to respond
751         * and send the feed back.
752         *
753         * @access public
754         * @since 1.0 Beta 3
755         * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
756         */
757        function set_timeout($timeout = 10)
758        {
759                $this->timeout = (int) $timeout;
760        }
761
762        /**
763         * Forces SimplePie to use fsockopen() instead of the preferred cURL
764         * functions.
765         *
766         * @access public
767         * @since 1.0 Beta 3
768         * @param bool $enable Force fsockopen() to be used
769         */
770        function force_fsockopen($enable = false)
771        {
772                $this->force_fsockopen = (bool) $enable;
773        }
774
775        /**
776         * Outputs the raw XML content of the feed, after it has gone through
777         * SimplePie's filters.
778         *
779         * Used only for debugging, this function will output the XML content as
780         * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
781         * before trying to parse it. Many parts of the feed are re-written in
782         * memory, and in the end, you have a parsable feed. XML dump shows you the
783         * actual XML that SimplePie tries to parse, which may or may not be very
784         * different from the original feed.
785         *
786         * @access public
787         * @since 1.0 Preview Release
788         * @param bool $enable Enable XML dump
789         */
790        function enable_xml_dump($enable = false)
791        {
792                $this->xml_dump = (bool) $enable;
793        }
794
795        /**
796         * Enables/disables caching in SimplePie.
797         *
798         * This option allows you to disable caching all-together in SimplePie.
799         * However, disabling the cache can lead to longer load times.
800         *
801         * @access public
802         * @since 1.0 Preview Release
803         * @param bool $enable Enable caching
804         */
805        function enable_cache($enable = true)
806        {
807                $this->cache = (bool) $enable;
808        }
809
810        /**
811         * Set the length of time (in seconds) that the contents of a feed
812         * will be cached.
813         *
814         * @access public
815         * @param int $seconds The feed content cache duration.
816         */
817        function set_cache_duration($seconds = 3600)
818        {
819                $this->cache_duration = (int) $seconds;
820        }
821
822        /**
823         * Set the length of time (in seconds) that the autodiscovered feed
824         * URL will be cached.
825         *
826         * @access public
827         * @param int $seconds The autodiscovered feed URL cache duration.
828         */
829        function set_autodiscovery_cache_duration($seconds = 604800)
830        {
831                $this->autodiscovery_cache_duration = (int) $seconds;
832        }
833
834        /**
835         * Set the file system location where the cached files should be stored.
836         *
837         * @access public
838         * @param string $location The file system location.
839         */
840        function set_cache_location($location = './cache')
841        {
842                $this->cache_location = (string) $location;
843        }
844
845        /**
846         * Determines whether feed items should be sorted into reverse chronological order.
847         *
848         * @access public
849         * @param bool $enable Sort as reverse chronological order.
850         */
851        function enable_order_by_date($enable = true)
852        {
853                $this->order_by_date = (bool) $enable;
854        }
855
856        /**
857         * Allows you to override the character encoding reported by the feed.
858         *
859         * @access public
860         * @param string $encoding Character encoding.
861         */
862        function set_input_encoding($encoding = false)
863        {
864                if ($encoding)
865                {
866                        $this->input_encoding = (string) $encoding;
867                }
868                else
869                {
870                        $this->input_encoding = false;
871                }
872        }
873
874        /**
875         * Set how much feed autodiscovery to do
876         *
877         * @access public
878         * @see SIMPLEPIE_LOCATOR_NONE
879         * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
880         * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
881         * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
882         * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
883         * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
884         * @see SIMPLEPIE_LOCATOR_ALL
885         * @param int $level Feed Autodiscovery Level (level can be a
886         * combination of the above constants, see bitwise OR operator)
887         */
888        function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
889        {
890                $this->autodiscovery = (int) $level;
891        }
892
893        /**
894         * Allows you to change which class SimplePie uses for caching.
895         * Useful when you are overloading or extending SimplePie's default classes.
896         *
897         * @access public
898         * @param string $class Name of custom class.
899         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
900         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
901         */
902        function set_cache_class($class = 'SimplePie_Cache')
903        {
904                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
905                {
906                        $this->cache_class = $class;
907                        return true;
908                }
909                return false;
910        }
911
912        /**
913         * Allows you to change which class SimplePie uses for auto-discovery.
914         * Useful when you are overloading or extending SimplePie's default classes.
915         *
916         * @access public
917         * @param string $class Name of custom class.
918         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
919         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
920         */
921        function set_locator_class($class = 'SimplePie_Locator')
922        {
923                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
924                {
925                        $this->locator_class = $class;
926                        return true;
927                }
928                return false;
929        }
930
931        /**
932         * Allows you to change which class SimplePie uses for XML parsing.
933         * Useful when you are overloading or extending SimplePie's default classes.
934         *
935         * @access public
936         * @param string $class Name of custom class.
937         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
938         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
939         */
940        function set_parser_class($class = 'SimplePie_Parser')
941        {
942                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
943                {
944                        $this->parser_class = $class;
945                        return true;
946                }
947                return false;
948        }
949
950        /**
951         * Allows you to change which class SimplePie uses for remote file fetching.
952         * Useful when you are overloading or extending SimplePie's default classes.
953         *
954         * @access public
955         * @param string $class Name of custom class.
956         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
957         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
958         */
959        function set_file_class($class = 'SimplePie_File')
960        {
961                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
962                {
963                        $this->file_class = $class;
964                        return true;
965                }
966                return false;
967        }
968
969        /**
970         * Allows you to change which class SimplePie uses for data sanitization.
971         * Useful when you are overloading or extending SimplePie's default classes.
972         *
973         * @access public
974         * @param string $class Name of custom class.
975         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
976         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
977         */
978        function set_sanitize_class($class = 'SimplePie_Sanitize')
979        {
980                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
981                {
982                        $this->sanitize =& new $class;
983                        return true;
984                }
985                return false;
986        }
987
988        /**
989         * Allows you to change which class SimplePie uses for handling feed items.
990         * Useful when you are overloading or extending SimplePie's default classes.
991         *
992         * @access public
993         * @param string $class Name of custom class.
994         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
995         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
996         */
997        function set_item_class($class = 'SimplePie_Item')
998        {
999                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1000                {
1001                        $this->item_class = $class;
1002                        return true;
1003                }
1004                return false;
1005        }
1006
1007        /**
1008         * Allows you to change which class SimplePie uses for handling author data.
1009         * Useful when you are overloading or extending SimplePie's default classes.
1010         *
1011         * @access public
1012         * @param string $class Name of custom class.
1013         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1014         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1015         */
1016        function set_author_class($class = 'SimplePie_Author')
1017        {
1018                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1019                {
1020                        $this->author_class = $class;
1021                        return true;
1022                }
1023                return false;
1024        }
1025
1026        /**
1027         * Allows you to change which class SimplePie uses for handling category data.
1028         * Useful when you are overloading or extending SimplePie's default classes.
1029         *
1030         * @access public
1031         * @param string $class Name of custom class.
1032         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1033         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1034         */
1035        function set_category_class($class = 'SimplePie_Category')
1036        {
1037                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1038                {
1039                        $this->category_class = $class;
1040                        return true;
1041                }
1042                return false;
1043        }
1044
1045        /**
1046         * Allows you to change which class SimplePie uses for feed enclosures.
1047         * Useful when you are overloading or extending SimplePie's default classes.
1048         *
1049         * @access public
1050         * @param string $class Name of custom class.
1051         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1052         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1053         */
1054        function set_enclosure_class($class = 'SimplePie_Enclosure')
1055        {
1056                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1057                {
1058                        $this->enclosure_class = $class;
1059                        return true;
1060                }
1061                return false;
1062        }
1063
1064        /**
1065         * Allows you to change which class SimplePie uses for <media:text> captions
1066         * Useful when you are overloading or extending SimplePie's default classes.
1067         *
1068         * @access public
1069         * @param string $class Name of custom class.
1070         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1071         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1072         */
1073        function set_caption_class($class = 'SimplePie_Caption')
1074        {
1075                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1076                {
1077                        $this->caption_class = $class;
1078                        return true;
1079                }
1080                return false;
1081        }
1082
1083        /**
1084         * Allows you to change which class SimplePie uses for <media:copyright>
1085         * Useful when you are overloading or extending SimplePie's default classes.
1086         *
1087         * @access public
1088         * @param string $class Name of custom class.
1089         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1090         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1091         */
1092        function set_copyright_class($class = 'SimplePie_Copyright')
1093        {
1094                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1095                {
1096                        $this->copyright_class = $class;
1097                        return true;
1098                }
1099                return false;
1100        }
1101
1102        /**
1103         * Allows you to change which class SimplePie uses for <media:credit>
1104         * Useful when you are overloading or extending SimplePie's default classes.
1105         *
1106         * @access public
1107         * @param string $class Name of custom class.
1108         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1109         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1110         */
1111        function set_credit_class($class = 'SimplePie_Credit')
1112        {
1113                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1114                {
1115                        $this->credit_class = $class;
1116                        return true;
1117                }
1118                return false;
1119        }
1120
1121        /**
1122         * Allows you to change which class SimplePie uses for <media:rating>
1123         * Useful when you are overloading or extending SimplePie's default classes.
1124         *
1125         * @access public
1126         * @param string $class Name of custom class.
1127         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1128         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1129         */
1130        function set_rating_class($class = 'SimplePie_Rating')
1131        {
1132                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1133                {
1134                        $this->rating_class = $class;
1135                        return true;
1136                }
1137                return false;
1138        }
1139
1140        /**
1141         * Allows you to change which class SimplePie uses for <media:restriction>
1142         * Useful when you are overloading or extending SimplePie's default classes.
1143         *
1144         * @access public
1145         * @param string $class Name of custom class.
1146         * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1147         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1148         */
1149        function set_restriction_class($class = 'SimplePie_Restriction')
1150        {
1151                if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1152                {
1153                        $this->restriction_class = $class;
1154                        return true;
1155                }
1156                return false;
1157        }
1158
1159        /**
1160         * Allows you to override the default user agent string.
1161         *
1162         * @access public
1163         * @param string $ua New user agent string.
1164         */
1165        function set_useragent($ua = SIMPLEPIE_USERAGENT)
1166        {
1167                $this->useragent = (string) $ua;
1168        }
1169
1170        /**
1171         * Set callback function to create cache filename with
1172         *
1173         * @access public
1174         * @param mixed $function Callback function
1175         */
1176        function set_cache_name_function($function = 'md5')
1177        {
1178                if (is_callable($function))
1179                {
1180                        $this->cache_name_function = $function;
1181                }
1182        }
1183
1184        /**
1185         * Set javascript query string parameter
1186         *
1187         * @access public
1188         * @param mixed $get Javascript query string parameter
1189         */
1190        function set_javascript($get = 'js')
1191        {
1192                if ($get)
1193                {
1194                        $this->javascript = (string) $get;
1195                }
1196                else
1197                {
1198                        $this->javascript = false;
1199                }
1200        }
1201
1202        /**
1203         * Set options to make SP as fast as possible.  Forgoes a
1204         * substantial amount of data sanitization in favor of speed.
1205         *
1206         * @access public
1207         * @param bool $set Whether to set them or not
1208         */
1209        function set_stupidly_fast($set = false)
1210        {
1211                if ($set)
1212                {
1213                        $this->enable_order_by_date(false);
1214                        $this->remove_div(false);
1215                        $this->strip_comments(false);
1216                        $this->strip_htmltags(false);
1217                        $this->strip_attributes(false);
1218                        $this->set_image_handler(false);
1219                }
1220        }
1221
1222        /**
1223         * Set maximum number of feeds to check with autodiscovery
1224         *
1225         * @access public
1226         * @param int $max Maximum number of feeds to check
1227         */
1228        function set_max_checked_feeds($max = 10)
1229        {
1230                $this->max_checked_feeds = (int) $max;
1231        }
1232
1233        function remove_div($enable = true)
1234        {
1235                $this->sanitize->remove_div($enable);
1236        }
1237
1238        function strip_htmltags($tags = '', $encode = null)
1239        {
1240                if ($tags === '')
1241                {
1242                        $tags = $this->strip_htmltags;
1243                }
1244                $this->sanitize->strip_htmltags($tags);
1245                if ($encode !== null)
1246                {
1247                        $this->sanitize->encode_instead_of_strip($tags);
1248                }
1249        }
1250
1251        function encode_instead_of_strip($enable = true)
1252        {
1253                $this->sanitize->encode_instead_of_strip($enable);
1254        }
1255
1256        function strip_attributes($attribs = '')
1257        {
1258                if ($attribs === '')
1259                {
1260                        $attribs = $this->strip_attributes;
1261                }
1262                $this->sanitize->strip_attributes($attribs);
1263        }
1264
1265        function set_output_encoding($encoding = 'UTF-8')
1266        {
1267                $this->sanitize->set_output_encoding($encoding);
1268        }
1269
1270        function strip_comments($strip = false)
1271        {
1272                $this->sanitize->strip_comments($strip);
1273        }
1274
1275        /**
1276         * Set element/attribute key/value pairs of HTML attributes
1277         * containing URLs that need to be resolved relative to the feed
1278         *
1279         * @access public
1280         * @since 1.0
1281         * @param array $element_attribute Element/attribute key/value pairs
1282         */
1283        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'))
1284        {
1285                $this->sanitize->set_url_replacements($element_attribute);
1286        }
1287
1288        /**
1289         * Set the handler to enable the display of cached favicons.
1290         *
1291         * @access public
1292         * @param str $page Web-accessible path to the handler_favicon.php file.
1293         * @param str $qs The query string that the value should be passed to.
1294         */
1295        function set_favicon_handler($page = false, $qs = 'i')
1296        {
1297                if ($page != false)
1298                {
1299                        $this->favicon_handler = $page . '?' . $qs . '=';
1300                }
1301                else
1302                {
1303                        $this->favicon_handler = '';
1304                }
1305        }
1306
1307        /**
1308         * Set the handler to enable the display of cached images.
1309         *
1310         * @access public
1311         * @param str $page Web-accessible path to the handler_image.php file.
1312         * @param str $qs The query string that the value should be passed to.
1313         */
1314        function set_image_handler($page = false, $qs = 'i')
1315        {
1316                if ($page != false)
1317                {
1318                        $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1319                }
1320                else
1321                {
1322                        $this->image_handler = '';
1323                }
1324        }
1325
1326        function init()
1327        {
1328                if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.1.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1329                {
1330                        return false;
1331                }
1332                if (isset($_GET[$this->javascript]))
1333                {
1334                        if (function_exists('ob_gzhandler'))
1335                        {
1336                                ob_start('ob_gzhandler');
1337                        }
1338                        header('Content-type: text/javascript; charset: UTF-8');
1339                        header('Cache-Control: must-revalidate');
1340                        header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1341                        ?>
1342function embed_odeo(link) {
1343        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>');
1344}
1345
1346function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1347        if (placeholder != '') {
1348                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>');
1349        }
1350        else {
1351                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>');
1352        }
1353}
1354
1355function embed_flash(bgcolor, width, height, link, loop, type) {
1356        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>');
1357}
1358
1359function embed_flv(width, height, link, placeholder, loop, player) {
1360        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>');
1361}
1362
1363function embed_wmedia(width, height, link) {
1364        document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1365}
1366                        <?php
1367                        exit;
1368                }
1369
1370                // Pass whatever was set with config options over to the sanitizer.
1371                $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1372                $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1373
1374                if ($this->feed_url !== null || $this->raw_data !== null)
1375                {
1376                        $this->data = array();
1377                        $this->multifeed_objects = array();
1378                        $cache = false;
1379
1380                        if ($this->feed_url !== null)
1381                        {
1382                                $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1383                                // Decide whether to enable caching
1384                                if ($this->cache && $parsed_feed_url['scheme'] !== '')
1385                                {
1386                                        $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1387                                }
1388                                // If it's enabled and we don't want an XML dump, use the cache
1389                                if ($cache && !$this->xml_dump)
1390                                {
1391                                        // Load the Cache
1392                                        $this->data = $cache->load();
1393                                        if (!empty($this->data))
1394                                        {
1395                                                // If the cache is for an outdated build of SimplePie
1396                                                if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1397                                                {
1398                                                        $cache->unlink();
1399                                                        $this->data = array();
1400                                                }
1401                                                // If we've hit a collision just rerun it with caching disabled
1402                                                elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1403                                                {
1404                                                        $cache = false;
1405                                                        $this->data = array();
1406                                                }
1407                                                // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1408                                                elseif (isset($this->data['feed_url']))
1409                                                {
1410                                                        // If the autodiscovery cache is still valid use it.
1411                                                        if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1412                                                        {
1413                                                                // Do not need to do feed autodiscovery yet.
1414                                                                if ($this->data['feed_url'] == $this->data['url'])
1415                                                                {
1416                                                                        $cache->unlink();
1417                                                                        $this->data = array();
1418                                                                }
1419                                                                else
1420                                                                {
1421                                                                        $this->set_feed_url($this->data['feed_url']);
1422                                                                        return $this->init();
1423                                                                }
1424                                                        }
1425                                                }
1426                                                // Check if the cache has been updated
1427                                                elseif ($cache->mtime() + $this->cache_duration < time())
1428                                                {
1429                                                        // If we have last-modified and/or etag set
1430                                                        if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1431                                                        {
1432                                                                $headers = array();
1433                                                                if (isset($this->data['headers']['last-modified']))
1434                                                                {
1435                                                                        $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1436                                                                }
1437                                                                if (isset($this->data['headers']['etag']))
1438                                                                {
1439                                                                        $headers['if-none-match'] = $this->data['headers']['etag'];
1440                                                                }
1441                                                                $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1442                                                                if ($file->success)
1443                                                                {
1444                                                                        if ($file->status_code == 304)
1445                                                                        {
1446                                                                                $cache->touch();
1447                                                                                return true;
1448                                                                        }
1449                                                                        else
1450                                                                        {
1451                                                                                $headers = $file->headers;
1452                                                                        }
1453                                                                }
1454                                                                else
1455                                                                {
1456                                                                        unset($file);
1457                                                                }
1458                                                        }
1459                                                }
1460                                                // If the cache is still valid, just return true
1461                                                else
1462                                                {
1463                                                        return true;
1464                                                }
1465                                        }
1466                                        // If the cache is empty, delete it
1467                                        else
1468                                        {
1469                                                $cache->unlink();
1470                                                $this->data = array();
1471                                        }
1472                                }
1473                                // 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.
1474                                if (!isset($file))
1475                                {
1476                                        if (SimplePie_Misc::is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1477                                        {
1478                                                $file =& $this->file;
1479                                        }
1480                                        else
1481                                        {
1482                                                $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1483                                        }
1484                                }
1485                                // If the file connection has an error, set SimplePie::error to that and quit
1486                                if (!$file->success)
1487                                {
1488                                        $this->error = $file->error;
1489                                        if (!empty($this->data))
1490                                        {
1491                                                return true;
1492                                        }
1493                                        else
1494                                        {
1495                                                return false;
1496                                        }
1497                                }
1498
1499                                // Check if the supplied URL is a feed, if it isn't, look for it.
1500                                $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds);
1501                                if (!$locate->is_feed($file))
1502                                {
1503                                        // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1504                                        unset($file);
1505                                        if ($file = $locate->find($this->autodiscovery))
1506                                        {
1507                                                if ($cache)
1508                                                {
1509                                                        if (!$cache->save(array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD)))
1510                                                        {
1511                                                                trigger_error("$cache->name is not writeable", E_USER_WARNING);
1512                                                        }
1513                                                        $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1514                                                }
1515                                                $this->feed_url = $file->url;
1516                                        }
1517                                        else
1518                                        {
1519                                                $this->error = "A feed could not be found at $this->feed_url";
1520                                                SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1521                                                return false;
1522                                        }
1523                                }
1524                                $locate = null;
1525
1526                                $headers = $file->headers;
1527                                $data = trim($file->body);
1528                                unset($file);
1529                        }
1530                        else
1531                        {
1532                                $data = $this->raw_data;
1533                        }
1534
1535                        // First check to see if input has been overridden.
1536                        if ($this->input_encoding !== false)
1537                        {
1538                                $encoding = $this->input_encoding;
1539                        }
1540                        // Second try HTTP headers
1541                        elseif (isset($headers['content-type']) && preg_match('/;[\x09\x20]*charset=([^;]*)/i', $headers['content-type'], $charset))
1542                        {
1543                                $encoding = $charset[1];
1544                        }
1545                        // Then prolog, if at the very start of the document
1546                        elseif (preg_match("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')[\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*')([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", $data, $prolog))
1547                        {
1548                                $encoding = substr($prolog[6], 1, -1);
1549                        }
1550                        // UTF-32 Big Endian BOM
1551                        elseif (strpos($data, "\x0\x0\xFE\xFF") === 0)
1552                        {
1553                                $encoding = 'UTF-32be';
1554                        }
1555                        // UTF-32 Little Endian BOM
1556                        elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
1557                        {
1558                                $encoding = 'UTF-32';
1559                        }
1560                        // UTF-16 Big Endian BOM
1561                        elseif (strpos($data, "\xFE\xFF") === 0)
1562                        {
1563                                $encoding = 'UTF-16be';
1564                        }
1565                        // UTF-16 Little Endian BOM
1566                        elseif (strpos($data, "\xFF\xFE") === 0)
1567                        {
1568                                $encoding = 'UTF-16le';
1569                        }
1570                        // UTF-8 BOM
1571                        elseif (strpos($data, "\xEF\xBB\xBF") === 0)
1572                        {
1573                                $encoding = 'UTF-8';
1574                        }
1575                        // Fallback to the default (US-ASCII for text/xml, ISO-8859-1 for text/* MIME types, UTF-8 otherwise)
1576                        elseif (isset($headers['content-type']) && strtolower(SimplePie_Misc::parse_mime($headers['content-type'])) == 'text/xml')
1577                        {
1578                                $encoding = 'US-ASCII';
1579                        }
1580                        elseif (isset($headers['content-type']) && SimplePie_Misc::stripos(SimplePie_Misc::parse_mime($headers['content-type']), 'text/') === 0)
1581                        {
1582                                $encoding = 'ISO-8859-1';
1583                        }
1584                        else
1585                        {
1586                                $encoding = 'UTF-8';
1587                        }
1588
1589                        // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1590                        if ($encoding != 'UTF-8')
1591                        {
1592                                $data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1593                        }
1594
1595                        // Strip illegal characters
1596                        $data = SimplePie_Misc::utf8_bad_replace($data);
1597
1598                        $parser =& new $this->parser_class();
1599                        $parser->pre_process($data, 'UTF-8');
1600                        // If we want the XML, just output that and quit
1601                        if ($this->xml_dump)
1602                        {
1603                                header('Content-type: text/xml; charset=UTF-8');
1604                                echo $data;
1605                                exit;
1606                        }
1607                        // If it's parsed fine
1608                        elseif ($parser->parse($data))
1609                        {
1610                                unset($data);
1611                                $this->data = $parser->get_data();
1612                                if (isset($this->data['child']))
1613                                {
1614                                        if (isset($headers))
1615                                        {
1616                                                $this->data['headers'] = $headers;
1617                                        }
1618                                        $this->data['build'] = SIMPLEPIE_BUILD;
1619
1620                                        // Cache the file if caching is enabled
1621                                        if ($cache && !$cache->save($this->data))
1622                                        {
1623                                                trigger_error("$cache->name is not writeable", E_USER_WARNING);
1624                                        }
1625                                        return true;
1626                                }
1627                                else
1628                                {
1629                                        $this->error = "A feed could not be found at $this->feed_url";
1630                                        SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1631                                        return false;
1632                                }
1633                        }
1634                        // If we have an error, just set SimplePie::error to it and quit
1635                        else
1636                        {
1637                                $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1638                                SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1639                                return false;
1640                        }
1641                }
1642                elseif (!empty($this->multifeed_url))
1643                {
1644                        $i = 0;
1645                        $success = 0;
1646                        $this->multifeed_objects = array();
1647                        foreach ($this->multifeed_url as $url)
1648                        {
1649                                if (SIMPLEPIE_PHP5)
1650                                {
1651                                        // This keyword needs to defy coding standards for PHP4 compatibility
1652                                        $this->multifeed_objects[$i] = clone($this);
1653                                }
1654                                else
1655                                {
1656                                        $this->multifeed_objects[$i] = $this;
1657                                }
1658                                $this->multifeed_objects[$i]->set_feed_url($url);
1659                                $success |= $this->multifeed_objects[$i]->init();
1660                                $i++;
1661                        }
1662                        return (bool) $success;
1663                }
1664                else
1665                {
1666                        return false;
1667                }
1668        }
1669
1670        /**
1671         * Return the error message for the occured error
1672         *
1673         * @access public
1674         * @return string Error message
1675         */
1676        function error()
1677        {
1678                return $this->error;
1679        }
1680
1681        function get_encoding()
1682        {
1683                return $this->sanitize->output_encoding;
1684        }
1685
1686        function handle_content_type($mime = 'text/html')
1687        {
1688                if (!headers_sent())
1689                {
1690                        $header = "Content-type: $mime;";
1691                        if ($this->get_encoding())
1692                        {
1693                                $header .= ' charset=' . $this->get_encoding();
1694                        }
1695                        else
1696                        {
1697                                $header .= ' charset=UTF-8';
1698                        }
1699                        header($header);
1700                }
1701        }
1702
1703        function get_type()
1704        {
1705                if (!isset($this->data['type']))
1706                {
1707                        $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1708                        if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1709                        {
1710                                $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1711                        }
1712                        elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1713                        {
1714                                $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1715                        }
1716                        elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1717                        {
1718                                if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1719                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1720                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1721                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1722                                {
1723                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1724                                }
1725                                if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1726                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1727                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1728                                || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1729                                {
1730                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1731                                }
1732                        }
1733                        elseif (isset($this->data['child']['']['rss']))
1734                        {
1735                                $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1736                                if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1737                                {
1738                                        switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1739                                        {
1740                                                case '0.91':
1741                                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1742                                                        if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1743                                                        {
1744                                                                switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1745                                                                {
1746                                                                        case '0':
1747                                                                                $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1748                                                                                break;
1749
1750                                                                        case '24':
1751                                                                                $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1752                                                                                break;
1753                                                                }
1754                                                        }
1755                                                        break;
1756
1757                                                case '0.92':
1758                                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1759                                                        break;
1760
1761                                                case '0.93':
1762                                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1763                                                        break;
1764
1765                                                case '0.94':
1766                                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1767                                                        break;
1768
1769                                                case '2.0':
1770                                                        $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1771                                                        break;
1772                                        }
1773                                }
1774                        }
1775                        else
1776                        {
1777                                $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1778                        }
1779                }
1780                return $this->data['type'];
1781        }
1782
1783        /**
1784         * Returns the URL for the favicon of the feed's website.
1785         *
1786         * @access public
1787         * @since 1.0
1788         */
1789        function get_favicon()
1790        {
1791                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1792                {
1793                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1794                }
1795                elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1796                {
1797                        $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1798
1799                        if ($this->cache && $this->favicon_handler)
1800                        {
1801                                $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $favicon), 'spi');
1802
1803                                if ($cache->load())
1804                                {
1805                                        return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1806                                }
1807                                else
1808                                {
1809                                        $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1810
1811                                        if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1812                                        {
1813                                                if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1814                                                {
1815                                                        return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1816                                                }
1817                                                else
1818                                                {
1819                                                        trigger_error("$cache->name is not writeable", E_USER_WARNING);
1820                                                        return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1821                                                }
1822                                        }
1823                                }
1824                        }
1825                        else
1826                        {
1827                                return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1828                        }
1829                }
1830                return false;
1831        }
1832
1833        /**
1834         * @todo If we have a perm redirect we should return the new URL
1835         * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1836         * @todo Also, |atom:link|@rel=self
1837         */
1838        function subscribe_url()
1839        {
1840                if ($this->feed_url !== null)
1841                {
1842                        return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1843                }
1844                else
1845                {
1846                        return null;
1847                }
1848        }
1849
1850        function subscribe_feed()
1851        {
1852                if ($this->feed_url !== null)
1853                {
1854                        return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1855                }
1856                else
1857                {
1858                        return null;
1859                }
1860        }
1861
1862        function subscribe_outlook()
1863        {
1864                if ($this->feed_url !== null)
1865                {
1866                        return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1867                }
1868                else
1869                {
1870                        return null;
1871                }
1872        }
1873
1874        function subscribe_podcast()
1875        {
1876                if ($this->feed_url !== null)
1877                {
1878                        return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
1879                }
1880                else
1881                {
1882                        return null;
1883                }
1884        }
1885
1886        function subscribe_itunes()
1887        {
1888                if ($this->feed_url !== null)
1889                {
1890                        return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
1891                }
1892                else
1893                {
1894                        return null;
1895                }
1896        }
1897
1898        /**
1899         * Creates the subscribe_* methods' return data
1900         *
1901         * @access private
1902         * @param string $feed_url String to prefix to the feed URL
1903         * @param string $site_url String to prefix to the site URL (and
1904         * suffix to the feed URL)
1905         * @return mixed URL if feed exists, false otherwise
1906         */
1907        function subscribe_service($feed_url, $site_url = null)
1908        {
1909                if ($this->subscribe_url())
1910                {
1911                        $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->subscribe_url());
1912                        if ($site_url !== null && $this->get_link() !== null)
1913                        {
1914                                $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
1915                        }
1916                        return $return;
1917                }
1918                else
1919                {
1920                        return null;
1921                }
1922        }
1923
1924        function subscribe_aol()
1925        {
1926                return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
1927        }
1928
1929        function subscribe_bloglines()
1930        {
1931                return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
1932        }
1933
1934        function subscribe_eskobo()
1935        {
1936                return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
1937        }
1938
1939        function subscribe_feedfeeds()
1940        {
1941                return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
1942        }
1943
1944        function subscribe_feedster()
1945        {
1946                return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
1947        }
1948
1949        function subscribe_google()
1950        {
1951                return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
1952        }
1953
1954        function subscribe_gritwire()
1955        {
1956                return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
1957        }
1958
1959        function subscribe_msn()
1960        {
1961                return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
1962        }
1963
1964        function subscribe_netvibes()
1965        {
1966                return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
1967        }
1968
1969        function subscribe_newsburst()
1970        {
1971                return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
1972        }
1973
1974        function subscribe_newsgator()
1975        {
1976                return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
1977        }
1978
1979        function subscribe_odeo()
1980        {
1981                return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
1982        }
1983
1984        function subscribe_podnova()
1985        {
1986                return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
1987        }
1988
1989        function subscribe_rojo()
1990        {
1991                return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
1992        }
1993
1994        function subscribe_yahoo()
1995        {
1996                return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
1997        }
1998
1999        function get_feed_tags($namespace, $tag)
2000        {
2001                $type = $this->get_type();
2002                if ($type & SIMPLEPIE_TYPE_ATOM_10)
2003                {
2004                        if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2005                        {
2006                                return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2007                        }
2008                }
2009                if ($type & SIMPLEPIE_TYPE_ATOM_03)
2010                {
2011                        if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2012                        {
2013                                return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2014                        }
2015                }
2016                if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2017                {
2018                        if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2019                        {
2020                                return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2021                        }
2022                }
2023                if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2024                {
2025                        if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2026                        {
2027                                return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2028                        }
2029                }
2030                return null;
2031        }
2032
2033        function get_channel_tags($namespace, $tag)
2034        {
2035                $type = $this->get_type();
2036                if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2037                {
2038                        if ($return = $this->get_feed_tags($namespace, $tag))
2039                        {
2040                                return $return;
2041                        }
2042                }
2043                if ($type & SIMPLEPIE_TYPE_RSS_10)
2044                {
2045                        if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2046                        {
2047                                if (isset($channel[0]['child'][$namespace][$tag]))
2048                                {
2049                                        return $channel[0]['child'][$namespace][$tag];
2050                                }
2051                        }
2052                }
2053                if ($type & SIMPLEPIE_TYPE_RSS_090)
2054                {
2055                        if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2056                        {
2057                                if (isset($channel[0]['child'][$namespace][$tag]))
2058                                {
2059                                        return $channel[0]['child'][$namespace][$tag];
2060                                }
2061                        }
2062                }
2063                if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2064                {
2065                        if ($channel = $this->get_feed_tags('', 'channel'))
2066                        {
2067                                if (isset($channel[0]['child'][$namespace][$tag]))
2068                                {
2069                                        return $channel[0]['child'][$namespace][$tag];
2070                                }
2071                        }
2072                }
2073                return null;
2074        }
2075
2076        function get_image_tags($namespace, $tag)
2077        {
2078                $type = $this->get_type();
2079                if ($type & SIMPLEPIE_TYPE_RSS_10)
2080                {
2081                        if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2082                        {
2083                                if (isset($image[0]['child'][$namespace][$tag]))
2084                                {
2085                                        return $image[0]['child'][$namespace][$tag];
2086                                }
2087                        }
2088                }
2089                if ($type & SIMPLEPIE_TYPE_RSS_090)
2090                {
2091                        if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2092                        {
2093                                if (isset($image[0]['child'][$namespace][$tag]))
2094                                {
2095                                        return $image[0]['child'][$namespace][$tag];
2096                                }
2097                        }
2098                }
2099                if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2100                {
2101                        if ($image = $this->get_channel_tags('', 'image'))
2102                        {
2103                                if (isset($image[0]['child'][$namespace][$tag]))
2104                                {
2105                                        return $image[0]['child'][$namespace][$tag];
2106                                }
2107                        }
2108                }
2109                return null;
2110        }
2111
2112        function get_base($element = array())
2113        {
2114                if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2115                {
2116                        return $element['xml_base'];
2117                }
2118                elseif ($this->get_link() !== null)
2119                {
2120                        return $this->get_link();
2121                }
2122                elseif (isset($this->data['headers']['content-location']))
2123                {
2124                        return SimplePie_Misc::absolutize_url($this->data['headers']['content-location'], $this->subscribe_url());
2125                }
2126                else
2127                {
2128                        return $this->subscribe_url();
2129                }
2130        }
2131
2132        function sanitize($data, $type, $base = '')
2133        {
2134                return $this->sanitize->sanitize($data, $type, $base);
2135        }
2136
2137        function get_title()
2138        {
2139                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2140                {
2141                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2142                }
2143                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2144                {
2145                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2146                }
2147                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2148                {
2149                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2150                }
2151                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2152                {
2153                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2154                }
2155                elseif ($return = $this->get_channel_tags('', 'title'))
2156                {
2157                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2158                }
2159                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2160                {
2161                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2162                }
2163                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2164                {
2165                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2166                }
2167                else
2168                {
2169                        return null;
2170                }
2171        }
2172
2173        function get_link($key = 0, $rel = 'alternate')
2174        {
2175                $links = $this->get_links($rel);
2176                if (isset($links[$key]))
2177                {
2178                        return $links[$key];
2179                }
2180                else
2181                {
2182                        return null;
2183                }
2184        }
2185
2186        /**
2187         * Added for parity between the parent-level and the item/entry-level.
2188         */
2189        function get_permalink()
2190        {
2191                return $this->get_link(0);
2192        }
2193
2194        function get_links($rel = 'alternate')
2195        {
2196                if (!isset($this->data['links']))
2197                {
2198                        $this->data['links'] = array();
2199                        if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2200                        {
2201                                foreach ($links as $link)
2202                                {
2203                                        if (isset($link['attribs']['']['href']))
2204                                        {
2205                                                $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2206                                                $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2207                                        }
2208                                }
2209                        }
2210                        if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2211                        {
2212                                foreach ($links as $link)
2213                                {
2214                                        if (isset($link['attribs']['']['href']))
2215                                        {
2216                                                $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2217                                                $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2218
2219                                        }
2220                                }
2221                        }
2222                        if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2223                        {
2224                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2225                        }
2226                        if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2227                        {
2228                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2229                        }
2230                        if ($links = $this->get_channel_tags('', 'link'))
2231                        {
2232                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2233                        }
2234
2235                        $keys = array_keys($this->data['links']);
2236                        foreach ($keys as $key)
2237                        {
2238                                if (SimplePie_Misc::is_isegment_nz_nc($key))
2239                                {
2240                                        if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2241                                        {
2242                                                $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2243                                                $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2244                                        }
2245                                        else
2246                                        {
2247                                                $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2248                                        }
2249                                }
2250                                elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2251                                {
2252                                        $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2253                                }
2254                                $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2255                        }
2256                }
2257
2258                if (isset($this->data['links'][$rel]))
2259                {
2260                        return $this->data['links'][$rel];
2261                }
2262                else
2263                {
2264                        return null;
2265                }
2266        }
2267
2268        function get_description()
2269        {
2270                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2271                {
2272                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2273                }
2274                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2275                {
2276                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2277                }
2278                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2279                {
2280                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2281                }
2282                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2283                {
2284                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2285                }
2286                elseif ($return = $this->get_channel_tags('', 'description'))
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_DC_11, 'description'))
2291                {
2292                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2293                }
2294                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2295                {
2296                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2297                }
2298                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2299                {
2300                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2301                }
2302                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2303                {
2304                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2305                }
2306                else
2307                {
2308                        return null;
2309                }
2310        }
2311
2312        function get_copyright()
2313        {
2314                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2315                {
2316                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2317                }
2318                elseif ($return = $this->get_channel_tags('', 'copyright'))
2319                {
2320                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2321                }
2322                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2323                {
2324                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2325                }
2326                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2327                {
2328                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2329                }
2330                else
2331                {
2332                        return null;
2333                }
2334        }
2335
2336        function get_language()
2337        {
2338                if ($return = $this->get_channel_tags('', 'language'))
2339                {
2340                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2341                }
2342                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2343                {
2344                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2345                }
2346                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2347                {
2348                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2349                }
2350                elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2351                {
2352                        return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2353                }
2354                elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2355                {
2356                        return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2357                }
2358                elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2359                {
2360                        return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2361                }
2362                elseif (isset($this->data['headers']['content-language']))
2363                {
2364                        return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2365                }
2366                else
2367                {
2368                        return null;
2369                }
2370        }
2371
2372        function get_latitude()
2373        {
2374                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2375                {
2376                        return (float) $return[0]['data'];
2377                }
2378                elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2379                {
2380                        return (float) $match[1];
2381                }
2382                else
2383                {
2384                        return null;
2385                }
2386        }
2387
2388        function get_longitude()
2389        {
2390                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2391                {
2392                        return (float) $return[0]['data'];
2393                }
2394                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2395                {
2396                        return (float) $return[0]['data'];
2397                }
2398                elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2399                {
2400                        return (float) $match[2];
2401                }
2402                else
2403                {
2404                        return null;
2405                }
2406        }
2407
2408        function get_image_title()
2409        {
2410                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2411                {
2412                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2413                }
2414                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2415                {
2416                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2417                }
2418                elseif ($return = $this->get_image_tags('', 'title'))
2419                {
2420                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2421                }
2422                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2423                {
2424                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2425                }
2426                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2427                {
2428                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2429                }
2430                else
2431                {
2432                        return null;
2433                }
2434        }
2435
2436        function get_image_url()
2437        {
2438                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2439                {
2440                        return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2441                }
2442                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2443                {
2444                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2445                }
2446                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2447                {
2448                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2449                }
2450                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2451                {
2452                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2453                }
2454                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2455                {
2456                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2457                }
2458                elseif ($return = $this->get_image_tags('', 'url'))
2459                {
2460                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2461                }
2462                else
2463                {
2464                        return null;
2465                }
2466        }
2467
2468        function get_image_link()
2469        {
2470                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2471                {
2472                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2473                }
2474                elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2475                {
2476                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2477                }
2478                elseif ($return = $this->get_image_tags('', 'link'))
2479                {
2480                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2481                }
2482                else
2483                {
2484                        return null;
2485                }
2486        }
2487
2488        function get_image_width()
2489        {
2490                if ($return = $this->get_image_tags('', 'width'))
2491                {
2492                        return round($return[0]['data']);
2493                }
2494                elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2495                {
2496                        return 88.0;
2497                }
2498                else
2499                {
2500                        return null;
2501                }
2502        }
2503
2504        function get_image_height()
2505        {
2506                if ($return = $this->get_image_tags('', 'height'))
2507                {
2508                        return round($return[0]['data']);
2509                }
2510                elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2511                {
2512                        return 31.0;
2513                }
2514                else
2515                {
2516                        return null;
2517                }
2518        }
2519
2520        function get_item_quantity($max = 0)
2521        {
2522                $qty = count($this->get_items());
2523                if ($max == 0)
2524                {
2525                        return $qty;
2526                }
2527                else
2528                {
2529                        return ($qty > $max) ? $max : $qty;
2530                }
2531        }
2532
2533        function get_item($key = 0)
2534        {
2535                $items = $this->get_items();
2536                if (isset($items[$key]))
2537                {
2538                        return $items[$key];
2539                }
2540                else
2541                {
2542                        return null;
2543                }
2544        }
2545
2546        function get_items($start = 0, $end = 0)
2547        {
2548                if (!empty($this->multifeed_objects))
2549                {
2550                        return SimplePie::merge_items($this->multifeed_objects, $start, $end);
2551                }
2552                elseif (!isset($this->data['items']))
2553                {
2554                        if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2555                        {
2556                                $keys = array_keys($items);
2557                                foreach ($keys as $key)
2558                                {
2559                                        $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2560                                }
2561                        }
2562                        if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2563                        {
2564                                $keys = array_keys($items);
2565                                foreach ($keys as $key)
2566                                {
2567                                        $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2568                                }
2569                        }
2570                        if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2571                        {
2572                                $keys = array_keys($items);
2573                                foreach ($keys as $key)
2574                                {
2575                                        $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2576                                }
2577                        }
2578                        if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2579                        {
2580                                $keys = array_keys($items);
2581                                foreach ($keys as $key)
2582                                {
2583                                        $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2584                                }
2585                        }
2586                        if ($items = $this->get_channel_tags('', 'item'))
2587                        {
2588                                $keys = array_keys($items);
2589                                foreach ($keys as $key)
2590                                {
2591                                        $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2592                                }
2593                        }
2594                }
2595
2596                if (!empty($this->data['items']))
2597                {
2598                        // If we want to order it by date, check if all items have a date, and then sort it
2599                        if ($this->order_by_date)
2600                        {
2601                                if (!isset($this->data['ordered_items']))
2602                                {
2603                                        $do_sort = true;
2604                                        foreach ($this->data['items'] as $item)
2605                                        {
2606                                                if (!$item->get_date('U'))
2607                                                {
2608                                                        $do_sort = false;
2609                                                        break;
2610                                                }
2611                                        }
2612                                        $item = null;
2613                                        $this->data['ordered_items'] = $this->data['items'];
2614                                        if ($do_sort)
2615                                        {
2616                                                usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2617                                        }
2618                                }
2619                                $items = $this->data['ordered_items'];
2620                        }
2621                        else
2622                        {
2623                                $items = $this->data['items'];
2624                        }
2625
2626                        // Slice the data as desired
2627                        if ($end == 0)
2628                        {
2629                                return array_slice($items, $start);
2630                        }
2631                        else
2632                        {
2633                                return array_slice($items, $start, $end);
2634                        }
2635                }
2636                else
2637                {
2638                        return array();
2639                }
2640        }
2641
2642        function sort_items($a, $b)
2643        {
2644                return $a->get_date('U') <= $b->get_date('U');
2645        }
2646
2647        function merge_items($urls, $start = 0, $end = 0)
2648        {
2649                if (is_array($urls) && sizeof($urls) > 0)
2650                {
2651                        $items = array();
2652                        foreach ($urls as $arg)
2653                        {
2654                                if (SimplePie_Misc::is_a($arg, 'SimplePie'))
2655                                {
2656                                        $items = array_merge($items, $arg->get_items());
2657                                }
2658                                else
2659                                {
2660                                        trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
2661                                }
2662                        }
2663
2664                        $do_sort = true;
2665                        foreach ($items as $item)
2666                        {
2667                                if (!$item->get_date('U'))
2668                                {
2669                                        $do_sort = false;
2670                                        break;
2671                                }
2672                        }
2673                        $item = null;
2674                        if ($do_sort)
2675                        {
2676                                usort($items, array('SimplePie', 'sort_items'));
2677                        }
2678
2679                        if ($end == 0)
2680                        {
2681                                return array_slice($items, $start);
2682                        }
2683                        else
2684                        {
2685                                return array_slice($items, $start, $end);
2686                        }
2687                }
2688                else
2689                {
2690                        trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
2691                        return array();
2692                }
2693        }
2694}
2695
2696class SimplePie_Item
2697{
2698        var $feed;
2699        var $data = array();
2700
2701        function SimplePie_Item($feed, $data)
2702        {
2703                $this->feed = $feed;
2704                $this->data = $data;
2705        }
2706
2707        function __toString()
2708        {
2709                return md5(serialize($this->data));
2710        }
2711
2712        function get_item_tags($namespace, $tag)
2713        {
2714                if (isset($this->data['child'][$namespace][$tag]))
2715                {
2716                        return $this->data['child'][$namespace][$tag];
2717                }
2718                else
2719                {
2720                        return null;
2721                }
2722        }
2723
2724        function get_base($element = array())
2725        {
2726                return $this->feed->get_base($element);
2727        }
2728
2729        function sanitize($data, $type, $base = '')
2730        {
2731                return $this->feed->sanitize($data, $type, $base);
2732        }
2733
2734        function get_feed()
2735        {
2736                return $this->feed;
2737        }
2738
2739        function get_id($hash = false)
2740        {
2741                if ($hash)
2742                {
2743                        return $this->__toString();
2744                }
2745                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
2746                {
2747                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2748                }
2749                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
2750                {
2751                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752                }
2753                elseif ($return = $this->get_item_tags('', 'guid'))
2754                {
2755                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2756                }
2757                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
2758                {
2759                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2760                }
2761                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
2762                {
2763                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2764                }
2765                elseif (($return = $this->get_permalink()) !== null)
2766                {
2767                        return $return;
2768                }
2769                elseif (($return = $this->get_title()) !== null)
2770                {
2771                        return $return;
2772                }
2773                else
2774                {
2775                        return $this->__toString();
2776                }
2777        }
2778
2779        function get_title()
2780        {
2781                if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2782                {
2783                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2784                }
2785                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2786                {
2787                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2788                }
2789                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2790                {
2791                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2792                }
2793                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2794                {
2795                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2796                }
2797                elseif ($return = $this->get_item_tags('', 'title'))
2798                {
2799                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2800                }
2801                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2802                {
2803                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2804                }
2805                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2806                {
2807                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2808                }
2809                else
2810                {
2811                        return null;
2812                }
2813        }
2814
2815        function get_description($description_only = false)
2816        {
2817                if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
2818                {
2819                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2820                }
2821                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
2822                {
2823                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2824                }
2825                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2826                {
2827                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2828                }
2829                elseif ($return = $this->get_item_tags('', 'description'))
2830                {
2831                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2832                }
2833                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2834                {
2835                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2836                }
2837                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2838                {
2839                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2840                }
2841                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2842                {
2843                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2844                }
2845                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2846                {
2847                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2848                }
2849                elseif (!$description_only)
2850                {
2851                        return $this->get_content(true);
2852                }
2853                else
2854                {
2855                        return null;
2856                }
2857        }
2858
2859        function get_content($content_only = false)
2860        {
2861                if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
2862                {
2863                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2864                }
2865                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
2866                {
2867                        return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2868                }
2869                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
2870                {
2871                        return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2872                }
2873                elseif (!$content_only)
2874                {
2875                        return $this->get_description(true);
2876                }
2877                else
2878                {
2879                        return null;
2880                }
2881        }
2882
2883        function get_category($key = 0)
2884        {
2885                $categories = $this->get_categories();
2886                if (isset($categories[$key]))
2887                {
2888                        return $categories[$key];
2889                }
2890                else
2891                {
2892                        return null;
2893                }
2894        }
2895
2896        function get_categories()
2897        {
2898                $categories = array();
2899
2900                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2901                {
2902                        $term = null;
2903                        $scheme = null;
2904                        $label = null;
2905                        if (isset($category['attribs']['']['term']))
2906                        {
2907                                $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2908                        }
2909                        if (isset($category['attribs']['']['scheme']))
2910                        {
2911                                $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2912                        }
2913                        if (isset($category['attribs']['']['label']))
2914                        {
2915                                $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2916                        }
2917                        $categories[] =& new $this->feed->category_class($term, $scheme, $label);
2918                }
2919                foreach ((array) $this->get_item_tags('', 'category') as $category)
2920                {
2921                        $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2922                }
2923                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2924                {
2925                        $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2926                }
2927                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2928                {
2929                        $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2930                }
2931
2932                if (!empty($categories))
2933                {
2934                        return SimplePie_Misc::array_unique($categories);
2935                }
2936                else
2937                {
2938                        return null;
2939                }
2940        }
2941
2942        function get_author($key = 0)
2943        {
2944                $authors = $this->get_authors();
2945                if (isset($authors[$key]))
2946                {
2947                        return $authors[$key];
2948                }
2949                else
2950                {
2951                        return null;
2952                }
2953        }
2954
2955        /**
2956         * @todo Atom inheritance (item author, source author, feed author)
2957         */
2958        function get_authors()
2959        {
2960                $authors = array();
2961                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2962                {
2963                        $name = null;
2964                        $uri = null;
2965                        $email = null;
2966                        if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2967                        {
2968                                $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2969                        }
2970                        if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2971                        {
2972                                $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]));
2973                        }
2974                        if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2975                        {
2976                                $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2977                        }
2978                        if ($name !== null || $email !== null || $uri !== null)
2979                        {
2980                                $authors[] =& new $this->feed->author_class($name, $uri, $email);
2981                        }
2982                }
2983                if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2984                {
2985                        $name = null;
2986                        $url = null;
2987                        $email = null;
2988                        if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2989                        {
2990                                $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2991                        }
2992                        if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2993                        {
2994                                $uri = $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]));
2995                        }
2996                        if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2997                        {
2998                                $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2999                        }
3000                        if ($name !== null || $email !== null || $uri !== null)
3001                        {
3002                                $authors[] =& new $this->feed->author_class($name, $url, $email);
3003                        }
3004                }
3005                if ($author = $this->get_item_tags('', 'author'))
3006                {
3007                        $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3008                }
3009                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3010                {
3011                        $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3012                }
3013                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3014                {
3015                        $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3016                }
3017                foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3018                {
3019                        $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3020                }
3021
3022                if (!empty($authors))
3023                {
3024                        return SimplePie_Misc::array_unique($authors);
3025                }
3026                else
3027                {
3028                        return null;
3029                }
3030        }
3031
3032        function get_date($date_format = 'j F Y, g:i a')
3033        {
3034                if (!isset($this->data['date']))
3035                {
3036                        if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3037                        {
3038                                $this->data['date']['raw'] = $return[0]['data'];
3039                        }
3040                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3041                        {
3042                                $this->data['date']['raw'] = $return[0]['data'];
3043                        }
3044                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3045                        {
3046                                $this->data['date']['raw'] = $return[0]['data'];
3047                        }
3048                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3049                        {
3050                                $this->data['date']['raw'] = $return[0]['data'];
3051                        }
3052                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3053                        {
3054                                $this->data['date']['raw'] = $return[0]['data'];
3055                        }
3056                        elseif ($return = $this->get_item_tags('', 'pubDate'))
3057                        {
3058                                $this->data['date']['raw'] = $return[0]['data'];
3059                        }
3060                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3061                        {
3062                                $this->data['date']['raw'] = $return[0]['data'];
3063                        }
3064                        elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3065                        {
3066                                $this->data['date']['raw'] = $return[0]['data'];
3067                        }
3068
3069                        if (!empty($this->data['date']['raw']))
3070                        {
3071                                $this->data['date']['parsed'] = SimplePie_Misc::parse_date($this->data['date']['raw']);
3072                        }
3073                        else
3074                        {
3075                                $this->data['date'] = null;
3076                        }
3077                }
3078                if ($this->data['date'])
3079                {
3080                        $date_format = (string) $date_format;
3081                        switch ($date_format)
3082                        {
3083                                case '':
3084                                        return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3085
3086                                case 'U':
3087                                        return $this->data['date']['parsed'];
3088
3089                                default:
3090                                        return date($date_format, $this->data['date']['parsed']);
3091                        }
3092                }
3093                else
3094                {
3095                        return null;
3096                }
3097        }
3098
3099        function get_local_date($date_format = '%c')
3100        {
3101                if (!$date_format)
3102                {
3103                        return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3104                }
3105                elseif (($date = $this->get_date('U')) !== null)
3106                {
3107                        return strftime($date_format, $date);
3108                }
3109                else
3110                {
3111                        return null;
3112                }
3113        }
3114
3115        function get_permalink()
3116        {
3117                $link = $this->get_link();
3118                $enclosure = $this->get_enclosure(0);
3119                if ($link !== null)
3120                {
3121                        return $link;
3122                }
3123                elseif ($enclosure !== null)
3124                {
3125                        return $enclosure->get_link();
3126                }
3127                else
3128                {
3129                        return null;
3130                }
3131        }
3132
3133        function get_link($key = 0, $rel = 'alternate')
3134        {
3135                $links = $this->get_links($rel);
3136                if ($links[$key] !== null)
3137                {
3138                        return $links[$key];
3139                }
3140                else
3141                {
3142                        return null;
3143                }
3144        }
3145
3146        function get_links($rel = 'alternate')
3147        {
3148                if (!isset($this->data['links']))
3149                {
3150                        $this->data['links'] = array();
3151                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3152                        {
3153                                if (isset($link['attribs']['']['href']))
3154                                {
3155                                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3156                                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3157
3158                                }
3159                        }
3160                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3161                        {
3162                                if (isset($link['attribs']['']['href']))
3163                                {
3164                                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3165                                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3166                                }
3167                        }
3168                        if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3169                        {
3170                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3171                        }
3172                        if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3173                        {
3174                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3175                        }
3176                        if ($links = $this->get_item_tags('', 'link'))
3177                        {
3178                                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3179                        }
3180                        if ($links = $this->get_item_tags('', 'guid'))
3181                        {
3182                                if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3183                                {
3184                                        $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3185                                }
3186                        }
3187
3188                        $keys = array_keys($this->data['links']);
3189                        foreach ($keys as $key)
3190                        {
3191                                if (SimplePie_Misc::is_isegment_nz_nc($key))
3192                                {
3193                                        if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3194                                        {
3195                                                $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3196                                                $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3197                                        }
3198                                        else
3199                                        {
3200                                                $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3201                                        }
3202                                }
3203                                elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3204                                {
3205                                        $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3206                                }
3207                                $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3208                        }
3209                }
3210                if (isset($this->data['links'][$rel]))
3211                {
3212                        return $this->data['links'][$rel];
3213                }
3214                else
3215                {
3216                        return null;
3217                }
3218        }
3219
3220        /**
3221         * @todo Add ability to prefer one type of content over another (in a media group).
3222         */
3223        function get_enclosure($key = 0, $prefer = null)
3224        {
3225                $enclosures = $this->get_enclosures();
3226                if (isset($enclosures[$key]))
3227                {
3228                        return $enclosures[$key];
3229                }
3230                else
3231                {
3232                        return null;
3233                }
3234        }
3235
3236        /**
3237         * Grabs all available enclosures (podcasts, etc.)
3238         *
3239         * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3240         *
3241         * 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.
3242         *
3243         * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3244         * @todo Add support for itunes: tags.  These should be relatively simple compared to media:.
3245         * @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).
3246         */
3247        function get_enclosures()
3248        {
3249                if (!isset($this->data['enclosures']))
3250                {
3251                        $this->data['enclosures'] = array();
3252
3253                        // Elements
3254                        $captions_parent = null;
3255                        $categories_parent = null;
3256                        $copyrights_parent = null;
3257                        $credits_parent = null;
3258                        $description_parent = null;
3259                        $duration_parent = null;
3260                        $hashes_parent = null;
3261                        $keywords_parent = null;
3262                        $player_parent = null;
3263                        $ratings_parent = null;
3264                        $restrictions_parent = null;
3265                        $thumbnails_parent = null;
3266                        $title_parent = null;
3267
3268                        // Let's do the channel and item-level ones first, and just re-use them if we need to.
3269                        $parent = $this->get_feed();
3270
3271                        // CAPTIONS
3272                        if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3273                        {
3274                                foreach ($captions as $caption)
3275                                {
3276                                        $caption_type = null;
3277                                        $caption_lang = null;
3278                                        $caption_startTime = null;
3279                                        $caption_endTime = null;
3280                                        $caption_text = null;
3281                                        if (isset($caption['attribs']['']['type']))
3282                                        {
3283                                                $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3284                                        }
3285                                        if (isset($caption['attribs']['']['lang']))
3286                                        {
3287                                                $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3288                                        }
3289                                        if (isset($caption['attribs']['']['start']))
3290                                        {
3291                                                $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3292                                        }
3293                                        if (isset($caption['attribs']['']['end']))
3294                                        {
3295                                                $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3296                                        }
3297                                        if (isset($caption['data']))
3298                                        {
3299                                                $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3300                                        }
3301                                        $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3302                                }
3303                        }
3304                        elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3305                        {
3306                                foreach ($captions as $caption)
3307                                {
3308                                        $caption_type = null;
3309                                        $caption_lang = null;
3310                                        $caption_startTime = null;
3311                                        $caption_endTime = null;
3312                                        $caption_text = null;
3313                                        if (isset($caption['attribs']['']['type']))
3314                                        {
3315                                                $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3316                                        }
3317                                        if (isset($caption['attribs']['']['lang']))
3318                                        {
3319                                                $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3320                                        }
3321                                        if (isset($caption['attribs']['']['start']))
3322                                        {
3323                                                $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3324                                        }
3325                                        if (isset($caption['attribs']['']['end']))
3326                                        {
3327                                                $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3328                                        }
3329                                        if (isset($caption['data']))
3330                                        {
3331                                                $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3332                                        }
3333                                        $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3334                                }
3335                        }
3336                        if (is_array($captions_parent))
3337                        {
3338                                $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3339                        }
3340
3341                        // CATEGORIES
3342                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3343                        {
3344                                $term = null;
3345                                $scheme = null;
3346                                $label = null;
3347                                if (isset($category['data']))
3348                                {
3349                                        $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3350                                }
3351                                if (isset($category['attribs']['']['scheme']))
3352                                {
3353                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3354                                }
3355                                else
3356                                {
3357                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
3358                                }
3359                                if (isset($category['attribs']['']['label']))
3360                                {
3361                                        $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3362                                }
3363                                $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3364                        }
3365                        foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3366                        {
3367                                $term = null;
3368                                $scheme = null;
3369                                $label = null;
3370                                if (isset($category['data']))
3371                                {
3372                                        $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3373                                }
3374                                if (isset($category['attribs']['']['scheme']))
3375                                {
3376                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3377                                }
3378                                else
3379                                {
3380                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
3381                                }
3382                                if (isset($category['attribs']['']['label']))
3383                                {
3384                                        $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3385                                }
3386                                $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3387                        }
3388                        foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3389                        {
3390                                $term = null;
3391                                $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3392                                $label = null;
3393                                if (isset($category['attribs']['']['text']))
3394                                {
3395                                        $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3396                                }
3397                                $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3398
3399                                if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3400                                {
3401                                        foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3402                                        {
3403                                                if (isset($subcategory['attribs']['']['text']))
3404                                                {
3405                                                        $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3406                                                }
3407                                                $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3408                                        }
3409                                }
3410                        }
3411                        if (is_array($categories_parent))
3412                        {
3413                                $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3414                        }
3415
3416                        // COPYRIGHT
3417                        if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3418                        {
3419                                $copyright_url = null;
3420                                $copyright_label = null;
3421                                if (isset($copyright[0]['attribs']['']['url']))
3422                                {
3423                                        $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3424                                }
3425                                if (isset($copyright[0]['data']))
3426                                {
3427                                        $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3428                                }
3429                                $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3430                        }
3431                        elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3432                        {
3433                                $copyright_url = null;
3434                                $copyright_label = null;
3435                                if (isset($copyright[0]['attribs']['']['url']))
3436                                {
3437                                        $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3438                                }
3439                                if (isset($copyright[0]['data']))
3440                                {
3441                                        $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3442                                }
3443                                $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3444                        }
3445
3446                        // CREDITS
3447                        if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3448                        {
3449                                foreach ($credits as $credit)
3450                                {
3451                                        $credit_role = null;
3452                                        $credit_scheme = null;
3453                                        $credit_name = null;
3454                                        if (isset($credit['attribs']['']['role']))
3455                                        {
3456                                                $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3457                                        }
3458                                        if (isset($credit['attribs']['']['scheme']))
3459                                        {
3460                                                $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3461                                        }
3462                                        else
3463                                        {
3464                                                $credit_scheme = 'urn:ebu';
3465                                        }
3466                                        if (isset($credit['data']))
3467                                        {
3468                                                $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3469                                        }
3470                                        $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3471                                }
3472                        }
3473                        elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3474                        {
3475                                foreach ($credits as $credit)
3476                                {
3477                                        $credit_role = null;
3478                                        $credit_scheme = null;
3479                                        $credit_name = null;
3480                                        if (isset($credit['attribs']['']['role']))
3481                                        {
3482                                                $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3483                                        }
3484                                        if (isset($credit['attribs']['']['scheme']))
3485                                        {
3486                                                $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3487                                        }
3488                                        else
3489                                        {
3490                                                $credit_scheme = 'urn:ebu';
3491                                        }
3492                                        if (isset($credit['data']))
3493                                        {
3494                                                $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3495                                        }
3496                                        $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3497                                }
3498                        }
3499                        if (is_array($credits_parent))
3500                        {
3501                                $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3502                        }
3503
3504                        // DESCRIPTION
3505                        if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3506                        {
3507                                if (isset($description_parent[0]['data']))
3508                                {
3509                                        $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3510                                }
3511                        }
3512                        elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3513                        {
3514                                if (isset($description_parent[0]['data']))
3515                                {
3516                                        $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3517                                }
3518                        }
3519
3520                        // DURATION
3521                        if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3522                        {
3523                                $seconds = null;
3524                                $minutes = null;
3525                                $hours = null;
3526                                if (isset($duration_parent[0]['data']))
3527                                {
3528                                        $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3529                                        if (sizeof($temp) > 0)
3530                                        {
3531                                                (int) $seconds = array_pop($temp);
3532                                        }
3533                                        if (sizeof($temp) > 0)
3534                                        {
3535                                                (int) $minutes = array_pop($temp);
3536                                                $seconds += $minutes * 60;
3537                                        }
3538                                        if (sizeof($temp) > 0)
3539                                        {
3540                                                (int) $hours = array_pop($temp);
3541                                                $seconds += $hours * 3600;
3542                                        }
3543                                        unset($temp);
3544                                        $duration_parent = $seconds;
3545                                }
3546                        }
3547
3548                        // HASHES
3549                        if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3550                        {
3551                                foreach ($hashes_iterator as $hash)
3552                                {
3553                                        $value = null;
3554                                        $algo = null;
3555                                        if (isset($hash['data']))
3556                                        {
3557                                                $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3558                                        }
3559                                        if (isset($hash['attribs']['']['algo']))
3560                                        {
3561                                                $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3562                                        }
3563                                        else
3564                                        {
3565                                                $algo = 'md5';
3566                                        }
3567                                        $hashes_parent[] = $algo.':'.$value;
3568                                }
3569                        }
3570                        elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3571                        {
3572                                foreach ($hashes_iterator as $hash)
3573                                {
3574                                        $value = null;
3575                                        $algo = null;
3576                                        if (isset($hash['data']))
3577                                        {
3578                                                $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3579                                        }
3580                                        if (isset($hash['attribs']['']['algo']))
3581                                        {
3582                                                $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3583                                        }
3584                                        else
3585                                        {
3586                                                $algo = 'md5';
3587                                        }
3588                                        $hashes_parent[] = $algo.':'.$value;
3589                                }
3590                        }
3591                        if (is_array($hashes_parent))
3592                        {
3593                                $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
3594                        }
3595
3596                        // KEYWORDS
3597                        if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3598                        {
3599                                if (isset($keywords[0]['data']))
3600                                {
3601                                        $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3602                                        foreach ($temp as $word)
3603                                        {
3604                                                $keywords_parent[] = trim($word);
3605                                        }
3606                                }
3607                                unset($temp);
3608                        }
3609                        elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3610                        {
3611                                if (isset($keywords[0]['data']))
3612                                {
3613                                        $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3614                                        foreach ($temp as $word)
3615                                        {
3616                                                $keywords_parent[] = trim($word);
3617                                        }
3618                                }
3619                                unset($temp);
3620                        }
3621                        elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3622                        {
3623                                if (isset($keywords[0]['data']))
3624                                {
3625                                        $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3626                                        foreach ($temp as $word)
3627                                        {
3628                                                $keywords_parent[] = trim($word);
3629                                        }
3630                                }
3631                                unset($temp);
3632                        }
3633                        elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3634                        {
3635                                if (isset($keywords[0]['data']))
3636                                {
3637                                        $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3638                                        foreach ($temp as $word)
3639                                        {
3640                                                $keywords_parent[] = trim($word);
3641                                        }
3642                                }
3643                                unset($temp);
3644                        }
3645                        if (is_array($keywords_parent))
3646                        {
3647                                $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
3648                        }
3649
3650                        // PLAYER
3651                        if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3652                        {
3653                                if (isset($player_parent[0]['attribs']['']['url']))
3654                                {
3655                                        $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3656                                }
3657                        }
3658                        elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3659                        {
3660                                if (isset($player_parent[0]['attribs']['']['url']))
3661                                {
3662                                        $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3663                                }
3664                        }
3665
3666                        // RATINGS
3667                        if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3668                        {
3669                                foreach ($ratings as $rating)
3670                                {
3671                                        $rating_scheme = null;
3672                                        $rating_value = null;
3673                                        if (isset($rating['attribs']['']['scheme']))
3674                                        {
3675                                                $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3676                                        }
3677                                        else
3678                                        {
3679                                                $rating_scheme = 'urn:simple';
3680                                        }
3681                                        if (isset($rating['data']))
3682                                        {
3683                                                $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3684                                        }
3685                                        $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3686                                }
3687                        }
3688                        elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3689                        {
3690                                foreach ($ratings as $rating)
3691                                {
3692                                        $rating_scheme = 'urn:itunes';
3693                                        $rating_value = null;
3694                                        if (isset($rating['data']))
3695                                        {
3696                                                $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3697                                        }
3698                                        $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3699                                }
3700                        }
3701                        elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3702                        {
3703                                foreach ($ratings as $rating)
3704                                {
3705                                        $rating_scheme = null;
3706                                        $rating_value = null;
3707                                        if (isset($rating['attribs']['']['scheme']))
3708                                        {
3709                                                $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3710                                        }
3711                                        else
3712                                        {
3713                                                $rating_scheme = 'urn:simple';
3714                                        }
3715                                        if (isset($rating['data']))
3716                                        {
3717                                                $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3718                                        }
3719                                        $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3720                                }
3721                        }
3722                        elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3723                        {
3724                                foreach ($ratings as $rating)
3725                                {
3726                                        $rating_scheme = 'urn:itunes';
3727                                        $rating_value = null;
3728                                        if (isset($rating['data']))
3729                                        {
3730                                                $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3731                                        }
3732                                        $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3733                                }
3734                        }
3735                        if (is_array($ratings_parent))
3736                        {
3737                                $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
3738                        }
3739
3740                        // RESTRICTIONS
3741                        if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3742                        {
3743                                foreach ($restrictions as $restriction)
3744                                {
3745                                        $restriction_relationship = null;
3746                                        $restriction_type = null;
3747                                        $restriction_value = null;
3748                                        if (isset($restriction['attribs']['']['relationship']))
3749                                        {
3750                                                $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3751                                        }
3752                                        if (isset($restriction['attribs']['']['type']))
3753                                        {
3754                                                $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3755                                        }
3756                                        if (isset($restriction['data']))
3757                                        {
3758                                                $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3759                                        }
3760                                        $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3761                                }
3762                        }
3763                        elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3764                        {
3765                                foreach ($restrictions as $restriction)
3766                                {
3767                                        $restriction_relationship = 'allow';
3768                                        $restriction_type = null;
3769                                        $restriction_value = 'itunes';
3770                                        if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3771                                        {
3772                                                $restriction_relationship = 'deny';
3773                                        }
3774                                        $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3775                                }
3776                        }
3777                        elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3778                        {
3779                                foreach ($restrictions as $restriction)
3780                                {
3781                                        $restriction_relationship = null;
3782                                        $restriction_type = null;
3783                                        $restriction_value = null;
3784                                        if (isset($restriction['attribs']['']['relationship']))
3785                                        {
3786                                                $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3787                                        }
3788                                        if (isset($restriction['attribs']['']['type']))
3789                                        {
3790                                                $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3791                                        }
3792                                        if (isset($restriction['data']))
3793                                        {
3794                                                $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3795                                        }
3796                                        $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3797                                }
3798                        }
3799                        elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3800                        {
3801                                foreach ($restrictions as $restriction)
3802                                {
3803                                        $restriction_relationship = 'allow';
3804                                        $restriction_type = null;
3805                                        $restriction_value = 'itunes';
3806                                        if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3807                                        {
3808                                                $restriction_relationship = 'deny';
3809                                        }
3810                                        $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3811                                }
3812                        }
3813                        if (is_array($restrictions_parent))
3814                        {
3815                                $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
3816                        }
3817
3818                        // THUMBNAILS
3819                        if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3820                        {
3821                                foreach ($thumbnails as $thumbnail)
3822                                {
3823                                        if (isset($thumbnail['attribs']['']['url']))
3824                                        {
3825                                                $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3826                                        }
3827                                }
3828                        }
3829                        elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3830                        {
3831                                foreach ($thumbnails as $thumbnail)
3832                                {
3833                                        if (isset($thumbnail['attribs']['']['url']))
3834                                        {
3835                                                $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3836                                        }
3837                                }
3838                        }
3839
3840                        // TITLES
3841                        if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3842                        {
3843                                if (isset($title_parent[0]['data']))
3844                                {
3845                                        $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3846                                }
3847                        }
3848                        elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3849                        {
3850                                if (isset($title_parent[0]['data']))
3851                                {
3852                                        $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3853                                }
3854                        }
3855
3856                        // Clear the memory
3857                        unset($parent);
3858
3859                        // If we have media:group tags, loop through them.
3860                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
3861                        {
3862                                // If we have media:content tags, loop through them.
3863                                foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
3864                                {
3865                                        if (isset($content['attribs']['']['url']))
3866                                        {
3867                                                // Attributes
3868                                                $bitrate = null;
3869                                                $channels = null;
3870                                                $duration = null;
3871                                                $expression = null;
3872                                                $framerate = null;
3873                                                $height = null;
3874                                                $javascript = null;
3875                                                $lang = null;
3876                                                $length = null;
3877                                                $medium = null;
3878                                                $samplingrate = null;
3879                                                $type = null;
3880                                                $url = null;
3881                                                $width = null;
3882
3883                                                // Elements
3884                                                $captions = null;
3885                                                $categories = null;
3886                                                $copyrights = null;
3887                                                $credits = null;
3888                                                $description = null;
3889                                                $hashes = null;
3890                                                $keywords = null;
3891                                                $player = null;
3892                                                $ratings = null;
3893                                                $restrictions = null;
3894                                                $thumbnails = null;
3895                                                $title = null;
3896
3897                                                // Start checking the attributes of media:content
3898                                                if (isset($content['attribs']['']['bitrate']))
3899                                                {
3900                                                        $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3901                                                }
3902                                                if (isset($content['attribs']['']['channels']))
3903                                                {
3904                                                        $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
3905                                                }
3906                                                if (isset($content['attribs']['']['duration']))
3907                                                {
3908                                                        $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
3909                                                }
3910                                                else
3911                                                {
3912                                                        $duration = $duration_parent;
3913                                                }
3914                                                if (isset($content['attribs']['']['expression']))
3915                                                {
3916                                                        $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
3917                                                }
3918                                                if (isset($content['attribs']['']['framerate']))
3919                                                {
3920                                                        $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
3921                                                }
3922                                                if (isset($content['attribs']['']['height']))
3923                                                {
3924                                                        $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
3925                                                }
3926                                                if (isset($content['attribs']['']['lang']))
3927                                                {
3928                                                        $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3929                                                }
3930                                                if (isset($content['attribs']['']['fileSize']))
3931                                                {
3932                                                        $length = ceil($content['attribs']['']['fileSize']);
3933                                                }
3934                                                if (isset($content['attribs']['']['medium']))
3935                                                {
3936                                                        $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
3937                                                }
3938                                                if (isset($content['attribs']['']['samplingrate']))
3939                                                {
3940                                                        $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3941                                                }
3942                                                if (isset($content['attribs']['']['type']))
3943                                                {
3944                                                        $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3945                                                }
3946                                                if (isset($content['attribs']['']['width']))
3947                                                {
3948                                                        $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
3949                                                }
3950                                                $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3951
3952                                                // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
3953
3954                                                // CAPTIONS
3955                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3956                                                {
3957                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3958                                                        {
3959                                                                $caption_type = null;
3960                                                                $caption_lang = null;
3961                                                                $caption_startTime = null;
3962                                                                $caption_endTime = null;
3963                                                                $caption_text = null;
3964                                                                if (isset($caption['attribs']['']['type']))
3965                                                                {
3966                                                                        $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3967                                                                }
3968                                                                if (isset($caption['attribs']['']['lang']))
3969                                                                {
3970                                                                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3971                                                                }
3972                                                                if (isset($caption['attribs']['']['start']))
3973                                                                {
3974                                                                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3975                                                                }
3976                                                                if (isset($caption['attribs']['']['end']))
3977                                                                {
3978                                                                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3979                                                                }
3980                                                                if (isset($caption['data']))
3981                                                                {
3982                                                                        $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3983                                                                }
3984                                                                $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3985                                                        }
3986                                                        if (is_array($captions))
3987                                                        {
3988                                                                $captions = array_values(SimplePie_Misc::array_unique($captions));
3989                                                        }
3990                                                }
3991                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3992                                                {
3993                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3994                                                        {
3995                                                                $caption_type = null;
3996                                                                $caption_lang = null;
3997                                                                $caption_startTime = null;
3998                                                                $caption_endTime = null;
3999                                                                $caption_text = null;
4000                                                                if (isset($caption['attribs']['']['type']))
4001                                                                {
4002                                                                        $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4003                                                                }
4004                                                                if (isset($caption['attribs']['']['lang']))
4005                                                                {
4006                                                                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4007                                                                }
4008                                                                if (isset($caption['attribs']['']['start']))
4009                                                                {
4010                                                                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4011                                                                }
4012                                                                if (isset($caption['attribs']['']['end']))
4013                                                                {
4014                                                                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4015                                                                }
4016                                                                if (isset($caption['data']))
4017                                                                {
4018                                                                        $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4019                                                                }
4020                                                                $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4021                                                        }
4022                                                        if (is_array($captions))
4023                                                        {
4024                                                                $captions = array_values(SimplePie_Misc::array_unique($captions));
4025                                                        }
4026                                                }
4027                                                else
4028                                                {
4029                                                        $captions = $captions_parent;
4030                                                }
4031
4032                                                // CATEGORIES
4033                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4034                                                {
4035                                                        foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4036                                                        {
4037                                                                $term = null;
4038                                                                $scheme = null;
4039                                                                $label = null;
4040                                                                if (isset($category['data']))
4041                                                                {
4042                                                                        $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4043                                                                }
4044                                                                if (isset($category['attribs']['']['scheme']))
4045                                                                {
4046                                                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4047                                                                }
4048                                                                else
4049                                                                {
4050                                                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
4051                                                                }
4052                                                                if (isset($category['attribs']['']['label']))
4053                                                                {
4054                                                                        $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4055                                                                }
4056                                                                $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4057                                                        }
4058                                                }
4059                                                if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4060                                                {
4061                                                        foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4062                                                        {
4063                                                                $term = null;
4064                                                                $scheme = null;
4065                                                                $label = null;
4066                                                                if (isset($category['data']))
4067                                                                {
4068                                                                        $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4069                                                                }
4070                                                                if (isset($category['attribs']['']['scheme']))
4071                                                                {
4072                                                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4073                                                                }
4074                                                                else
4075                                                                {
4076                                                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
4077                                                                }
4078                                                                if (isset($category['attribs']['']['label']))
4079                                                                {
4080                                                                        $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4081                                                                }
4082                                                                $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4083                                                        }
4084                                                }
4085                                                if (is_array($categories) && is_array($categories_parent))
4086                                                {
4087                                                        $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4088                                                }
4089                                                elseif (is_array($categories))
4090                                                {
4091                                                        $categories = array_values(SimplePie_Misc::array_unique($categories));
4092                                                }
4093                                                elseif (is_array($categories_parent))
4094                                                {
4095                                                        $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4096                                                }
4097
4098                                                // COPYRIGHTS
4099                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4100                                                {
4101                                                        $copyright_url = null;
4102                                                        $copyright_label = null;
4103                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4104                                                        {
4105                                                                $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4106                                                        }
4107                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4108                                                        {
4109                                                                $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4110                                                        }
4111                                                        $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4112                                                }
4113                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4114                                                {
4115                                                        $copyright_url = null;
4116                                                        $copyright_label = null;
4117                                                        if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4118                                                        {
4119                                                                $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4120                                                        }
4121                                                        if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4122                                                        {
4123                                                                $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4124                                                        }
4125                                                        $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4126                                                }
4127                                                else
4128                                                {
4129                                                        $copyrights = $copyrights_parent;
4130                                                }
4131
4132                                                // CREDITS
4133                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4134                                                {
4135                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4136                                                        {
4137                                                                $credit_role = null;
4138                                                                $credit_scheme = null;
4139                                                                $credit_name = null;
4140                                                                if (isset($credit['attribs']['']['role']))
4141                                                                {
4142                                                                        $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4143                                                                }
4144                                                                if (isset($credit['attribs']['']['scheme']))
4145                                                                {
4146                                                                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4147                                                                }
4148                                                                else
4149                                                                {
4150                                                                        $credit_scheme = 'urn:ebu';
4151                                                                }
4152                                                                if (isset($credit['data']))
4153                                                                {
4154                                                                        $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4155                                                                }
4156                                                                $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4157                                                        }
4158                                                        if (is_array($credits))
4159                                                        {
4160                                                                $credits = array_values(SimplePie_Misc::array_unique($credits));
4161                                                        }
4162                                                }
4163                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4164                                                {
4165                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4166                                                        {
4167                                                                $credit_role = null;
4168                                                                $credit_scheme = null;
4169                                                                $credit_name = null;
4170                                                                if (isset($credit['attribs']['']['role']))
4171                                                                {
4172                                                                        $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4173                                                                }
4174                                                                if (isset($credit['attribs']['']['scheme']))
4175                                                                {
4176                                                                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4177                                                                }
4178                                                                else
4179                                                                {
4180                                                                        $credit_scheme = 'urn:ebu';
4181                                                                }
4182                                                                if (isset($credit['data']))
4183                                                                {
4184                                                                        $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4185                                                                }
4186                                                                $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4187                                                        }
4188                                                        if (is_array($credits))
4189                                                        {
4190                                                                $credits = array_values(SimplePie_Misc::array_unique($credits));
4191                                                        }
4192                                                }
4193                                                else
4194                                                {
4195                                                        $credits = $credits_parent;
4196                                                }
4197
4198                                                // DESCRIPTION
4199                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4200                                                {
4201                                                        $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4202                                                }
4203                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4204                                                {
4205                                                        $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4206                                                }
4207                                                else
4208                                                {
4209                                                        $description = $description_parent;
4210                                                }
4211
4212                                                // HASHES
4213                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4214                                                {
4215                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4216                                                        {
4217                                                                $value = null;
4218                                                                $algo = null;
4219                                                                if (isset($hash['data']))
4220                                                                {
4221                                                                        $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4222                                                                }
4223                                                                if (isset($hash['attribs']['']['algo']))
4224                                                                {
4225                                                                        $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4226                                                                }
4227                                                                else
4228                                                                {
4229                                                                        $algo = 'md5';
4230                                                                }
4231                                                                $hashes[] = $algo.':'.$value;
4232                                                        }
4233                                                        if (is_array($hashes))
4234                                                        {
4235                                                                $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4236                                                        }
4237                                                }
4238                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4239                                                {
4240                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4241                                                        {
4242                                                                $value = null;
4243                                                                $algo = null;
4244                                                                if (isset($hash['data']))
4245                                                                {
4246                                                                        $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4247                                                                }
4248                                                                if (isset($hash['attribs']['']['algo']))
4249                                                                {
4250                                                                        $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4251                                                                }
4252                                                                else
4253                                                                {
4254                                                                        $algo = 'md5';
4255                                                                }
4256                                                                $hashes[] = $algo.':'.$value;
4257                                                        }
4258                                                        if (is_array($hashes))
4259                                                        {
4260                                                                $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4261                                                        }
4262                                                }
4263                                                else
4264                                                {
4265                                                        $hashes = $hashes_parent;
4266                                                }
4267
4268                                                // KEYWORDS
4269                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4270                                                {
4271                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4272                                                        {
4273                                                                $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4274                                                                foreach ($temp as $word)
4275                                                                {
4276                                                                        $keywords[] = trim($word);
4277                                                                }
4278                                                                unset($temp);
4279                                                        }
4280                                                        if (is_array($keywords))
4281                                                        {
4282                                                                $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4283                                                        }
4284                                                }
4285                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4286                                                {
4287                                                        if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4288                                                        {
4289                                                                $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4290                                                                foreach ($temp as $word)
4291                                                                {
4292                                                                        $keywords[] = trim($word);
4293                                                                }
4294                                                                unset($temp);
4295                                                        }
4296                                                        if (is_array($keywords))
4297                                                        {
4298                                                                $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4299                                                        }
4300                                                }
4301                                                else
4302                                                {
4303                                                        $keywords = $keywords_parent;
4304                                                }
4305
4306                                                // PLAYER
4307                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4308                                                {
4309                                                        $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4310                                                }
4311                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4312                                                {
4313                                                        $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4314                                                }
4315                                                else
4316                                                {
4317                                                        $player = $player_parent;
4318                                                }
4319
4320                                                // RATINGS
4321                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4322                                                {
4323                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4324                                                        {
4325                                                                $rating_scheme = null;
4326                                                                $rating_value = null;
4327                                                                if (isset($rating['attribs']['']['scheme']))
4328                                                                {
4329                                                                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4330                                                                }
4331                                                                else
4332                                                                {
4333                                                                        $rating_scheme = 'urn:simple';
4334                                                                }
4335                                                                if (isset($rating['data']))
4336                                                                {
4337                                                                        $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4338                                                                }
4339                                                                $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4340                                                        }
4341                                                        if (is_array($ratings))
4342                                                        {
4343                                                                $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4344                                                        }
4345                                                }
4346                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4347                                                {
4348                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4349                                                        {
4350                                                                $rating_scheme = null;
4351                                                                $rating_value = null;
4352                                                                if (isset($rating['attribs']['']['scheme']))
4353                                                                {
4354                                                                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4355                                                                }
4356                                                                else
4357                                                                {
4358                                                                        $rating_scheme = 'urn:simple';
4359                                                                }
4360                                                                if (isset($rating['data']))
4361                                                                {
4362                                                                        $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4363                                                                }
4364                                                                $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4365                                                        }
4366                                                        if (is_array($ratings))
4367                                                        {
4368                                                                $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4369                                                        }
4370                                                }
4371                                                else
4372                                                {
4373                                                        $ratings = $ratings_parent;
4374                                                }
4375
4376                                                // RESTRICTIONS
4377                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4378                                                {
4379                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4380                                                        {
4381                                                                $restriction_relationship = null;
4382                                                                $restriction_type = null;
4383                                                                $restriction_value = null;
4384                                                                if (isset($restriction['attribs']['']['relationship']))
4385                                                                {
4386                                                                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4387                                                                }
4388                                                                if (isset($restriction['attribs']['']['type']))
4389                                                                {
4390                                                                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4391                                                                }
4392                                                                if (isset($restriction['data']))
4393                                                                {
4394                                                                        $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4395                                                                }
4396                                                                $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4397                                                        }
4398                                                        if (is_array($restrictions))
4399                                                        {
4400                                                                $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4401                                                        }
4402                                                }
4403                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4404                                                {
4405                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4406                                                        {
4407                                                                $restriction_relationship = null;
4408                                                                $restriction_type = null;
4409                                                                $restriction_value = null;
4410                                                                if (isset($restriction['attribs']['']['relationship']))
4411                                                                {
4412                                                                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4413                                                                }
4414                                                                if (isset($restriction['attribs']['']['type']))
4415                                                                {
4416                                                                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4417                                                                }
4418                                                                if (isset($restriction['data']))
4419                                                                {
4420                                                                        $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4421                                                                }
4422                                                                $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4423                                                        }
4424                                                        if (is_array($restrictions))
4425                                                        {
4426                                                                $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4427                                                        }
4428                                                }
4429                                                else
4430                                                {
4431                                                        $restrictions = $restrictions_parent;
4432                                                }
4433
4434                                                // THUMBNAILS
4435                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4436                                                {
4437                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4438                                                        {
4439                                                                $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4440                                                        }
4441                                                        if (is_array($thumbnails))
4442                                                        {
4443                                                                $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4444                                                        }
4445                                                }
4446                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4447                                                {
4448                                                        foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4449                                                        {
4450                                                                $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4451                                                        }
4452                                                        if (is_array($thumbnails))
4453                                                        {
4454                                                                $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4455                                                        }
4456                                                }
4457                                                else
4458                                                {
4459                                                        $thumbnails = $thumbnails_parent;
4460                                                }
4461
4462                                                // TITLES
4463                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4464                                                {
4465                                                        $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4466                                                }
4467                                                elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4468                                                {
4469                                                        $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4470                                                }
4471                                                else
4472                                                {
4473                                                        $title = $title_parent;
4474                                                }
4475
4476                                                $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);
4477                                        }
4478                                }
4479                        }
4480
4481                        // If we have standalone media:content tags, loop through them.
4482                        if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4483                        {
4484                                foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4485                                {
4486                                        if (isset($content['attribs']['']['url']))
4487                                        {
4488                                                // Attributes
4489                                                $bitrate = null;
4490                                                $channels = null;
4491                                                $duration = null;
4492                                                $expression = null;
4493                                                $framerate = null;
4494                                                $height = null;
4495                                                $javascript = null;
4496                                                $lang = null;
4497                                                $length = null;
4498                                                $medium = null;
4499                                                $samplingrate = null;
4500                                                $type = null;
4501                                                $url = null;
4502                                                $width = null;
4503
4504                                                // Elements
4505                                                $captions = null;
4506                                                $categories = null;
4507                                                $copyrights = null;
4508                                                $credits = null;
4509                                                $description = null;
4510                                                $hashes = null;
4511                                                $keywords = null;
4512                                                $player = null;
4513                                                $ratings = null;
4514                                                $restrictions = null;
4515                                                $thumbnails = null;
4516                                                $title = null;
4517
4518                                                // Start checking the attributes of media:content
4519                                                if (isset($content['attribs']['']['bitrate']))
4520                                                {
4521                                                        $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4522                                                }
4523                                                if (isset($content['attribs']['']['channels']))
4524                                                {
4525                                                        $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4526                                                }
4527                                                if (isset($content['attribs']['']['duration']))
4528                                                {
4529                                                        $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4530                                                }
4531                                                else
4532                                                {
4533                                                        $duration = $duration_parent;
4534                                                }
4535                                                if (isset($content['attribs']['']['expression']))
4536                                                {
4537                                                        $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4538                                                }
4539                                                if (isset($content['attribs']['']['framerate']))
4540                                                {
4541                                                        $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4542                                                }
4543                                                if (isset($content['attribs']['']['height']))
4544                                                {
4545                                                        $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4546                                                }
4547                                                if (isset($content['attribs']['']['lang']))
4548                                                {
4549                                                        $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4550                                                }
4551                                                if (isset($content['attribs']['']['fileSize']))
4552                                                {
4553                                                        $length = ceil($content['attribs']['']['fileSize']);
4554                                                }
4555                                                if (isset($content['attribs']['']['medium']))
4556                                                {
4557                                                        $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4558                                                }
4559                                                if (isset($content['attribs']['']['samplingrate']))
4560                                                {
4561                                                        $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4562                                                }
4563                                                if (isset($content['attribs']['']['type']))
4564                                                {
4565                                                        $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4566                                                }
4567                                                if (isset($content['attribs']['']['width']))
4568                                                {
4569                                                        $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4570                                                }
4571                                                $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4572
4573                                                // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4574
4575                                                // CAPTIONS
4576                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4577                                                {
4578                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4579                                                        {
4580                                                                $caption_type = null;
4581                                                                $caption_lang = null;
4582                                                                $caption_startTime = null;
4583                                                                $caption_endTime = null;
4584                                                                $caption_text = null;
4585                                                                if (isset($caption['attribs']['']['type']))
4586                                                                {
4587                                                                        $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4588                                                                }
4589                                                                if (isset($caption['attribs']['']['lang']))
4590                                                                {
4591                                                                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4592                                                                }
4593                                                                if (isset($caption['attribs']['']['start']))
4594                                                                {
4595                                                                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4596                                                                }
4597                                                                if (isset($caption['attribs']['']['end']))
4598                                                                {
4599                                                                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4600                                                                }
4601                                                                if (isset($caption['data']))
4602                                                                {
4603                                                                        $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4604                                                                }
4605                                                                $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4606                                                        }
4607                                                        if (is_array($captions))
4608                                                        {
4609                                                                $captions = array_values(SimplePie_Misc::array_unique($captions));
4610                                                        }
4611                                                }
4612                                                else
4613                                                {
4614                                                        $captions = $captions_parent;
4615                                                }
4616
4617                                                // CATEGORIES
4618                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4619                                                {
4620                                                        foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4621                                                        {
4622                                                                $term = null;
4623                                                                $scheme = null;
4624                                                                $label = null;
4625                                                                if (isset($category['data']))
4626                                                                {
4627                                                                        $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4628                                                                }
4629                                                                if (isset($category['attribs']['']['scheme']))
4630                                                                {
4631                                                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4632                                                                }
4633                                                                else
4634                                                                {
4635                                                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
4636                                                                }
4637                                                                if (isset($category['attribs']['']['label']))
4638                                                                {
4639                                                                        $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4640                                                                }
4641                                                                $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4642                                                        }
4643                                                }
4644                                                if (is_array($categories) && is_array($categories_parent))
4645                                                {
4646                                                        $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4647                                                }
4648                                                elseif (is_array($categories))
4649                                                {
4650                                                        $categories = array_values(SimplePie_Misc::array_unique($categories));
4651                                                }
4652                                                elseif (is_array($categories_parent))
4653                                                {
4654                                                        $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4655                                                }
4656                                                else
4657                                                {
4658                                                        $categories = null;
4659                                                }
4660
4661                                                // COPYRIGHTS
4662                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4663                                                {
4664                                                        $copyright_url = null;
4665                                                        $copyright_label = null;
4666                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4667                                                        {
4668                                                                $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4669                                                        }
4670                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4671                                                        {
4672                                                                $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4673                                                        }
4674                                                        $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4675                                                }
4676                                                else
4677                                                {
4678                                                        $copyrights = $copyrights_parent;
4679                                                }
4680
4681                                                // CREDITS
4682                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4683                                                {
4684                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4685                                                        {
4686                                                                $credit_role = null;
4687                                                                $credit_scheme = null;
4688                                                                $credit_name = null;
4689                                                                if (isset($credit['attribs']['']['role']))
4690                                                                {
4691                                                                        $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4692                                                                }
4693                                                                if (isset($credit['attribs']['']['scheme']))
4694                                                                {
4695                                                                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4696                                                                }
4697                                                                else
4698                                                                {
4699                                                                        $credit_scheme = 'urn:ebu';
4700                                                                }
4701                                                                if (isset($credit['data']))
4702                                                                {
4703                                                                        $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4704                                                                }
4705                                                                $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4706                                                        }
4707                                                        if (is_array($credits))
4708                                                        {
4709                                                                $credits = array_values(SimplePie_Misc::array_unique($credits));
4710                                                        }
4711                                                }
4712                                                else
4713                                                {
4714                                                        $credits = $credits_parent;
4715                                                }
4716
4717                                                // DESCRIPTION
4718                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4719                                                {
4720                                                        $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4721                                                }
4722                                                else
4723                                                {
4724                                                        $description = $description_parent;
4725                                                }
4726
4727                                                // HASHES
4728                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4729                                                {
4730                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4731                                                        {
4732                                                                $value = null;
4733                                                                $algo = null;
4734                                                                if (isset($hash['data']))
4735                                                                {
4736                                                                        $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4737                                                                }
4738                                                                if (isset($hash['attribs']['']['algo']))
4739                                                                {
4740                                                                        $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4741                                                                }
4742                                                                else
4743                                                                {
4744                                                                        $algo = 'md5';
4745                                                                }
4746                                                                $hashes[] = $algo.':'.$value;
4747                                                        }
4748                                                        if (is_array($hashes))
4749                                                        {
4750                                                                $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4751                                                        }
4752                                                }
4753                                                else
4754                                                {
4755                                                        $hashes = $hashes_parent;
4756                                                }
4757
4758                                                // KEYWORDS
4759                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4760                                                {
4761                                                        if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4762                                                        {
4763                                                                $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4764                                                                foreach ($temp as $word)
4765                                                                {
4766                                                                        $keywords[] = trim($word);
4767                                                                }
4768                                                                unset($temp);
4769                                                        }
4770                                                        if (is_array($keywords))
4771                                                        {
4772                                                                $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4773                                                        }
4774                                                }
4775                                                else
4776                                                {
4777                                                        $keywords = $keywords_parent;
4778                                                }
4779
4780                                                // PLAYER
4781                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4782                                                {
4783                                                        $player = $this->sanitize($content['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                                                else
4817                                                {
4818                                                        $ratings = $ratings_parent;
4819                                                }
4820
4821                                                // RESTRICTIONS
4822                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4823                                                {
4824                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4825                                                        {
4826                                                                $restriction_relationship = null;
4827                                                                $restriction_type = null;
4828                                                                $restriction_value = null;
4829                                                                if (isset($restriction['attribs']['']['relationship']))
4830                                                                {
4831                                                                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4832                                                                }
4833                                                                if (isset($restriction['attribs']['']['type']))
4834                                                                {
4835                                                                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4836                                                                }
4837                                                                if (isset($restriction['data']))
4838                                                                {
4839                                                                        $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4840                                                                }
4841                                                                $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4842                                                        }
4843                                                        if (is_array($restrictions))
4844                                                        {
4845                                                                $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4846                                                        }
4847                                                }
4848                                                else
4849                                                {
4850                                                        $restrictions = $restrictions_parent;
4851                                                }
4852
4853                                                // THUMBNAILS
4854                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4855                                                {
4856                                                        foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4857                                                        {
4858                                                                $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4859                                                        }
4860                                                        if (is_array($thumbnails))
4861                                                        {
4862                                                                $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4863                                                        }
4864                                                }
4865                                                else
4866                                                {
4867                                                        $thumbnails = $thumbnails_parent;
4868                                                }
4869
4870                                                // TITLES
4871                                                if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4872                                                {
4873                                                        $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4874                                                }
4875                                                else
4876                                                {
4877                                                        $title = $title_parent;
4878                                                }
4879
4880                                                $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);
4881                                        }
4882                                }
4883                        }
4884
4885                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
4886                        {
4887                                if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4888                                {
4889                                        // Attributes
4890                                        $bitrate = null;
4891                                        $channels = null;
4892                                        $duration = null;
4893                                        $expression = null;
4894                                        $framerate = null;
4895                                        $height = null;
4896                                        $javascript = null;
4897                                        $lang = null;
4898                                        $length = null;
4899                                        $medium = null;
4900                                        $samplingrate = null;
4901                                        $type = null;
4902                                        $url = null;
4903                                        $width = null;
4904
4905                                        $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4906                                        if (isset($link['attribs']['']['type']))
4907                                        {
4908                                                $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4909                                        }
4910                                        if (isset($link['attribs']['']['length']))
4911                                        {
4912                                                $length = ceil($link['attribs']['']['length']);
4913                                        }
4914
4915                                        // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4916                                        $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);
4917                                }
4918                        }
4919
4920                        foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
4921                        {
4922                                if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4923                                {
4924                                        // Attributes
4925                                        $bitrate = null;
4926                                        $channels = null;
4927                                        $duration = null;
4928                                        $expression = null;
4929                                        $framerate = null;
4930                                        $height = null;
4931                                        $javascript = null;
4932                                        $lang = null;
4933                                        $length = null;
4934                                        $medium = null;
4935                                        $samplingrate = null;
4936                                        $type = null;
4937                                        $url = null;
4938                                        $width = null;
4939
4940                                        $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4941                                        if (isset($link['attribs']['']['type']))
4942                                        {
4943                                                $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4944                                        }
4945                                        if (isset($link['attribs']['']['length']))
4946                                        {
4947                                                $length = ceil($link['attribs']['']['length']);
4948                                        }
4949
4950                                        // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4951                                        $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);
4952                                }
4953                        }
4954
4955                        if ($enclosure = $this->get_item_tags('', 'enclosure'))
4956                        {
4957                                if (isset($enclosure[0]['attribs']['']['url']))
4958                                {
4959                                        // Attributes
4960                                        $bitrate = null;
4961                                        $channels = null;
4962                                        $duration = null;
4963                                        $expression = null;
4964                                        $framerate = null;
4965                                        $height = null;
4966                                        $javascript = null;
4967                                        $lang = null;
4968                                        $length = null;
4969                                        $medium = null;
4970                                        $samplingrate = null;
4971                                        $type = null;
4972                                        $url = null;
4973                                        $width = null;
4974
4975                                        $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
4976                                        if (isset($enclosure[0]['attribs']['']['type']))
4977                                        {
4978                                                $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4979                                        }
4980                                        if (isset($enclosure[0]['attribs']['']['length']))
4981                                        {
4982                                                $length = ceil($enclosure[0]['attribs']['']['length']);
4983                                        }
4984
4985                                        // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4986                                        $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);
4987                                }
4988                        }
4989                        $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
4990                }
4991                if (!empty($this->data['enclosures']))
4992                {
4993                        return $this->data['enclosures'];
4994                }
4995                else
4996                {
4997                        return null;
4998                }
4999        }
5000
5001        function get_latitude()
5002        {
5003                if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5004                {
5005                        return (float) $return[0]['data'];
5006                }
5007                elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5008                {
5009                        return (float) $match[1];
5010                }
5011                else
5012                {
5013                        return null;
5014                }
5015        }
5016
5017        function get_longitude()
5018        {
5019                if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5020                {
5021                        return (float) $return[0]['data'];
5022                }
5023                elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5024                {
5025                        return (float) $return[0]['data'];
5026                }
5027                elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5028                {
5029                        return (float) $match[2];
5030                }
5031                else
5032                {
5033                        return null;
5034                }
5035        }
5036
5037        /**
5038         * Creates the add_to_* methods' return data
5039         *
5040         * @access private
5041         * @param string $item_url String to prefix to the item permalink
5042         * @param string $title_url String to prefix to the item title
5043         * (and suffix to the item permalink)
5044         * @return mixed URL if feed exists, false otherwise
5045         */
5046        function add_to_service($item_url, $title_url = null)
5047        {
5048                if ($this->get_permalink() !== null)
5049                {
5050                        $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5051                        if ($title_url !== null && $this->get_title() !== null)
5052                        {
5053                                $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5054                        }
5055                        return $return;
5056                }
5057                else
5058                {
5059                        return null;
5060                }
5061        }
5062
5063        function add_to_blinklist()
5064        {
5065                return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5066        }
5067
5068        function add_to_blogmarks()
5069        {
5070                return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5071        }
5072
5073        function add_to_delicious()
5074        {
5075                return $this->add_to_service('http://del.icio.us/post/?v=3&url=', '&title=');
5076        }
5077
5078        function add_to_digg()
5079        {
5080                return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5081        }
5082
5083        function add_to_furl()
5084        {
5085                return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5086        }
5087
5088        function add_to_magnolia()
5089        {
5090                return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5091        }
5092
5093        function add_to_myweb20()
5094        {
5095                return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5096        }
5097
5098        function add_to_newsvine()
5099        {
5100                return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5101        }
5102
5103        function add_to_reddit()
5104        {
5105                return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5106        }
5107
5108        function add_to_segnalo()
5109        {
5110                return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5111        }
5112
5113        function add_to_simpy()
5114        {
5115                return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5116        }
5117
5118        function add_to_spurl()
5119        {
5120                return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5121        }
5122
5123        function add_to_wists()
5124        {
5125                return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5126        }
5127
5128        function search_technorati()
5129        {
5130                return $this->add_to_service('http://www.technorati.com/search/');
5131        }
5132}
5133
5134class SimplePie_Author
5135{
5136        var $name;
5137        var $link;
5138        var $email;
5139
5140        // Constructor, used to input the data
5141        function SimplePie_Author($name = null, $link = null, $email = null)
5142        {
5143                $this->name = $name;
5144                $this->link = $link;
5145                $this->email = $email;
5146        }
5147
5148        function __toString()
5149        {
5150                // There is no $this->data here
5151                return md5(serialize($this));
5152        }
5153
5154        function get_name()
5155        {
5156                if ($this->name !== null)
5157                {
5158                        return $this->name;
5159                }
5160                else
5161                {
5162                        return null;
5163                }
5164        }
5165
5166        function get_link()
5167        {
5168                if ($this->link !== null)
5169                {
5170                        return $this->link;
5171                }
5172                else
5173                {
5174                        return null;
5175                }
5176        }
5177
5178        function get_email()
5179        {
5180                if ($this->email !== null)
5181                {
5182                        return $this->email;
5183                }
5184                else
5185                {
5186                        return null;
5187                }
5188        }
5189}
5190
5191class SimplePie_Category
5192{
5193        var $term;
5194        var $scheme;
5195        var $label;
5196
5197        // Constructor, used to input the data
5198        function SimplePie_Category($term = null, $scheme = null, $label = null)
5199        {
5200                $this->term = $term;
5201                $this->scheme = $scheme;
5202                $this->label = $label;
5203        }
5204
5205        function __toString()
5206        {
5207                // There is no $this->data here
5208                return md5(serialize($this));
5209        }
5210
5211        function get_term()
5212        {
5213                if ($this->term !== null)
5214                {
5215                        return $this->term;
5216                }
5217                else
5218                {
5219                        return null;
5220                }
5221        }
5222
5223        function get_scheme()
5224        {
5225                if ($this->scheme !== null)
5226                {
5227                        return $this->scheme;
5228                }
5229                else
5230                {
5231                        return null;
5232                }
5233        }
5234
5235        function get_label()
5236        {
5237                if ($this->label !== null)
5238                {
5239                        return $this->label;
5240                }
5241                else
5242                {
5243                        return $this->get_term();
5244                }
5245        }
5246}
5247
5248class SimplePie_Enclosure
5249{
5250        var $bitrate;
5251        var $captions;
5252        var $categories;
5253        var $channels;
5254        var $copyright;
5255        var $credits;
5256        var $description;
5257        var $duration;
5258        var $expression;
5259        var $framerate;
5260        var $handler;
5261        var $hashes;
5262        var $height;
5263        var $javascript;
5264        var $keywords;
5265        var $lang;
5266        var $length;
5267        var $link;
5268        var $medium;
5269        var $player;
5270        var $ratings;
5271        var $restrictions;
5272        var $samplingrate;
5273        var $thumbnails;
5274        var $title;
5275        var $type;
5276        var $width;
5277
5278        // Constructor, used to input the data
5279        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)
5280        {
5281                $this->bitrate = $bitrate;
5282                $this->captions = $captions;
5283                $this->categories = $categories;
5284                $this->channels = $channels;
5285                $this->copyright = $copyright;
5286                $this->credits = $credits;
5287                $this->description = $description;
5288                $this->duration = $duration;
5289                $this->expression = $expression;
5290                $this->framerate = $framerate;
5291                $this->hashes = $hashes;
5292                $this->height = $height;
5293                $this->javascript = $javascript;
5294                $this->keywords = $keywords;
5295                $this->lang = $lang;
5296                $this->length = $length;
5297                $this->link = $link;
5298                $this->medium = $medium;
5299                $this->player = $player;
5300                $this->ratings = $ratings;
5301                $this->restrictions = $restrictions;
5302                $this->samplingrate = $samplingrate;
5303                $this->thumbnails = $thumbnails;
5304                $this->title = $title;
5305                $this->type = $type;
5306                $this->width = $width;
5307                if (class_exists('idna_convert'))
5308                {
5309                        $idn =& new idna_convert;
5310                        $parsed = SimplePie_Misc::parse_url($link);
5311                        $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
5312                }
5313                $this->handler = $this->get_handler(); // Needs to load last
5314        }
5315
5316        function __toString()
5317        {
5318                // There is no $this->data here
5319                return md5(serialize($this));
5320        }
5321
5322        function get_bitrate()
5323        {
5324                if ($this->bitrate !== null)
5325                {
5326                        return $this->bitrate;
5327                }
5328                else
5329                {
5330                        return null;
5331                }
5332        }
5333
5334        function get_caption($key = 0)
5335        {
5336                $captions = $this->get_captions();
5337                if (isset($captions[$key]))
5338                {
5339                        return $captions[$key];
5340                }
5341                else
5342                {
5343                        return null;
5344                }
5345        }
5346
5347        function get_captions()
5348        {
5349                if ($this->captions !== null)
5350                {
5351                        return $this->captions;
5352                }
5353                else
5354                {
5355                        return null;
5356                }
5357        }
5358
5359        function get_category($key = 0)
5360        {
5361                $categories = $this->get_categories();
5362                if (isset($categories[$key]))
5363                {
5364                        return $categories[$key];
5365                }
5366                else
5367                {
5368                        return null;
5369                }
5370        }
5371
5372        function get_categories()
5373        {
5374                if ($this->categories !== null)
5375                {
5376                        return $this->categories;
5377                }
5378                else
5379                {
5380                        return null;
5381                }
5382        }
5383
5384        function get_channels()
5385        {
5386                if ($this->channels !== null)
5387                {
5388                        return $this->channels;
5389                }
5390                else
5391                {
5392                        return null;
5393                }
5394        }
5395
5396        function get_copyright()
5397        {
5398                if ($this->copyright !== null)
5399                {
5400                        return $this->copyright;
5401                }
5402                else
5403                {
5404                        return null;
5405                }
5406        }
5407
5408        function get_credit($key = 0)
5409        {
5410                $credits = $this->get_credits();
5411                if (isset($credits[$key]))
5412                {
5413                        return $credits[$key];
5414                }
5415                else
5416                {
5417                        return null;
5418                }
5419        }
5420
5421        function get_credits()
5422        {
5423                if ($this->credits !== null)
5424                {
5425                        return $this->credits;
5426                }
5427                else
5428                {
5429                        return null;
5430                }
5431        }
5432
5433        function get_description()
5434        {
5435                if ($this->description !== null)
5436                {
5437                        return $this->description;
5438                }
5439                else
5440                {
5441                        return null;
5442                }
5443        }
5444
5445        function get_duration($convert = false)
5446        {
5447                if ($this->duration !== null)
5448                {
5449                        if ($convert)
5450                        {
5451                                $time = SimplePie_Misc::time_hms($this->duration);
5452                                return $time;
5453                        }
5454                        else
5455                        {
5456                                return $this->duration;
5457                        }
5458                }
5459                else
5460                {
5461                        return null;
5462                }
5463        }
5464
5465        function get_expression()
5466        {
5467                if ($this->expression !== null)
5468                {
5469                        return $this->expression;
5470                }
5471                else
5472                {
5473                        return 'full';
5474                }
5475        }
5476
5477        function get_extension()
5478        {
5479                if ($this->link !== null)
5480                {
5481                        $url = SimplePie_Misc::parse_url($this->link);
5482                        if ($url['path'] !== '')
5483                        {
5484                                return pathinfo($url['path'], PATHINFO_EXTENSION);
5485                        }
5486                }
5487                return null;
5488        }
5489
5490        function get_framerate()
5491        {
5492                if ($this->framerate !== null)
5493                {
5494                        return $this->framerate;
5495                }
5496                else
5497                {
5498                        return null;
5499                }
5500        }
5501
5502        function get_handler()
5503        {
5504                return $this->get_real_type(true);
5505        }
5506
5507        function get_hash($key = 0)
5508        {
5509                $hashes = $this->get_hashes();
5510                if (isset($hashes[$key]))
5511                {
5512                        return $hashes[$key];
5513                }
5514                else
5515                {
5516                        return null;
5517                }
5518        }
5519
5520        function get_hashes()
5521        {
5522                if ($this->hashes !== null)
5523                {
5524                        return $this->hashes;
5525                }
5526                else
5527                {
5528                        return null;
5529                }
5530        }
5531
5532        function get_height()
5533        {
5534                if ($this->height !== null)
5535                {
5536                        return $this->height;
5537                }
5538                else
5539                {
5540                        return null;
5541                }
5542        }
5543
5544        function get_language()
5545        {
5546                if ($this->lang !== null)
5547                {
5548                        return $this->lang;
5549                }
5550                else
5551                {
5552                        return null;
5553                }
5554        }
5555
5556        function get_keyword($key = 0)
5557        {
5558                $keywords = $this->get_keywords();
5559                if (isset($keywords[$key]))
5560                {
5561                        return $keywords[$key];
5562                }
5563                else
5564                {
5565                        return null;
5566                }
5567        }
5568
5569        function get_keywords()
5570        {
5571                if ($this->keywords !== null)
5572                {
5573                        return $this->keywords;
5574                }
5575                else
5576                {
5577                        return null;
5578                }
5579        }
5580
5581        function get_length()
5582        {
5583                if ($this->length !== null)
5584                {
5585                        return $this->length;
5586                }
5587                else
5588                {
5589                        return null;
5590                }
5591        }
5592
5593        function get_link()
5594        {
5595                if ($this->link !== null)
5596                {
5597                        return urldecode($this->link);
5598                }
5599                else
5600                {
5601                        return null;
5602                }
5603        }
5604
5605        function get_medium()
5606        {
5607                if ($this->medium !== null)
5608                {
5609                        return $this->medium;
5610                }
5611                else
5612                {
5613                        return null;
5614                }
5615        }
5616
5617        function get_player()
5618        {
5619                if ($this->player !== null)
5620                {
5621                        return $this->player;
5622                }
5623                else
5624                {
5625                        return null;
5626                }
5627        }
5628
5629        function get_rating($key = 0)
5630        {
5631                $ratings = $this->get_ratings();
5632                if (isset($ratings[$key]))
5633                {
5634                        return $ratings[$key];
5635                }
5636                else
5637                {
5638                        return null;
5639                }
5640        }
5641
5642        function get_ratings()
5643        {
5644                if ($this->ratings !== null)
5645                {
5646                        return $this->ratings;
5647                }
5648                else
5649                {
5650                        return null;
5651                }
5652        }
5653
5654        function get_restriction($key = 0)
5655        {
5656                $restrictions = $this->get_restrictions();
5657                if (isset($restrictions[$key]))
5658                {
5659                        return $restrictions[$key];
5660                }
5661                else
5662                {
5663                        return null;
5664                }
5665        }
5666
5667        function get_restrictions()
5668        {
5669                if ($this->restrictions !== null)
5670                {
5671                        return $this->restrictions;
5672                }
5673                else
5674                {
5675                        return null;
5676                }
5677        }
5678
5679        function get_sampling_rate()
5680        {
5681                if ($this->samplingrate !== null)
5682                {
5683                        return $this->samplingrate;
5684                }
5685                else
5686                {
5687                        return null;
5688                }
5689        }
5690
5691        function get_size()
5692        {
5693                $length = $this->get_length();
5694                if ($length !== null)
5695                {
5696                        return round($length/1048576, 2);
5697                }
5698                else
5699                {
5700                        return null;
5701                }
5702        }
5703
5704        function get_thumbnail($key = 0)
5705        {
5706                $thumbnails = $this->get_thumbnails();
5707                if (isset($thumbnails[$key]))
5708                {
5709                        return $thumbnails[$key];
5710                }
5711                else
5712                {
5713                        return null;
5714                }
5715        }
5716
5717        function get_thumbnails()
5718        {
5719                if ($this->thumbnails !== null)
5720                {
5721                        return $this->thumbnails;
5722                }
5723                else
5724                {
5725                        return null;
5726                }
5727        }
5728
5729        function get_title()
5730        {
5731                if ($this->title !== null)
5732                {
5733                        return $this->title;
5734                }
5735                else
5736                {
5737                        return null;
5738                }
5739        }
5740
5741        function get_type()
5742        {
5743                if ($this->type !== null)
5744                {
5745                        return $this->type;
5746                }
5747                else
5748                {
5749                        return null;
5750                }
5751        }
5752
5753        function get_width()
5754        {
5755                if ($this->width !== null)
5756                {
5757                        return $this->width;
5758                }
5759                else
5760                {
5761                        return null;
5762                }
5763        }
5764
5765        function native_embed($options='')
5766        {
5767                return $this->embed($options, true);
5768        }
5769
5770        /**
5771         * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
5772         */
5773        function embed($options = '', $native = false)
5774        {
5775                // Set up defaults
5776                $audio = '';
5777                $video = '';
5778                $alt = '';
5779                $altclass = '';
5780                $loop = 'false';
5781                $width = 'auto';
5782                $height = 'auto';
5783                $bgcolor = '#ffffff';
5784                $mediaplayer = '';
5785                $widescreen = false;
5786                $handler = $this->get_handler();
5787                $type = $this->get_real_type();
5788
5789                // Process options and reassign values as necessary
5790                if (is_array($options))
5791                {
5792                        extract($options);
5793                }
5794                else
5795                {
5796                        $options = explode(',', $options);
5797                        foreach($options as $option)
5798                        {
5799                                $opt = explode(':', $option, 2);
5800                                if (isset($opt[0], $opt[1]))
5801                                {
5802                                        $opt[0] = trim($opt[0]);
5803                                        $opt[1] = trim($opt[1]);
5804                                        switch ($opt[0])
5805                                        {
5806                                                case 'audio':
5807                                                        $audio = $opt[1];
5808                                                        break;
5809
5810                                                case 'video':
5811                                                        $video = $opt[1];
5812                                                        break;
5813
5814                                                case 'alt':
5815                                                        $alt = $opt[1];
5816                                                        break;
5817
5818                                                case 'altclass':
5819                                                        $altclass = $opt[1];
5820                                                        break;
5821
5822                                                case 'loop':
5823                                                        $loop = $opt[1];
5824                                                        break;
5825
5826                                                case 'width':
5827                                                        $width = $opt[1];
5828                                                        break;
5829
5830                                                case 'height':
5831                                                        $height = $opt[1];
5832                                                        break;
5833
5834                                                case 'bgcolor':
5835                                                        $bgcolor = $opt[1];
5836                                                        break;
5837
5838                                                case 'mediaplayer':
5839                                                        $mediaplayer = $opt[1];
5840                                                        break;
5841
5842                                                case 'widescreen':
5843                                                        $widescreen = $opt[1];
5844                                                        break;
5845                                        }
5846                                }
5847                        }
5848                }
5849
5850                $mime = explode('/', $type, 2);
5851                $mime = $mime[0];
5852
5853                // Process values for 'auto'
5854                if ($width == 'auto')
5855                {
5856                        if ($mime == 'video')
5857                        {
5858                                if ($height == 'auto')
5859                                {
5860                                        $width = 480;
5861                                }
5862                                elseif ($widescreen)
5863                                {
5864                                        $width = round((intval($height)/9)*16);
5865                                }
5866                                else
5867                                {
5868                                        $width = round((intval($height)/3)*4);
5869                                }
5870                        }
5871                        else
5872                        {
5873                                $width = '100%';
5874                        }
5875                }
5876
5877                if ($height == 'auto')
5878                {
5879                        if ($mime == 'audio')
5880                        {
5881                                $height = 0;
5882                        }
5883                        elseif ($mime == 'video')
5884                        {
5885                                if ($width == 'auto')
5886                                {
5887                                        if ($widescreen)
5888                                        {
5889                                                $height = 270;
5890                                        }
5891                                        else
5892                                        {
5893                                                $height = 360;
5894                                        }
5895                                }
5896                                elseif ($widescreen)
5897                                {
5898                                        $height = round((intval($width)/16)*9);
5899                                }
5900                                else
5901                                {
5902                                        $height = round((intval($width)/4)*3);
5903                                }
5904                        }
5905                        else
5906                        {
5907                                $height = 376;
5908                        }
5909                }
5910                elseif ($mime == 'audio')
5911                {
5912                        $height = 0;
5913                }
5914
5915                // Set proper placeholder value
5916                if ($mime == 'audio')
5917                {
5918                        $placeholder = $audio;
5919                }
5920                elseif ($mime == 'video')
5921                {
5922                        $placeholder = $video;
5923                }
5924
5925                $embed = '';
5926
5927                // Make sure the JS library is included
5928                if (!$native)
5929                {
5930                        static $javascript_outputted = null;
5931                        if (!$javascript_outputted && $this->javascript)
5932                        {
5933                                $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
5934                                $javascript_outputted = true;
5935                        }
5936                }
5937
5938                // Odeo Feed MP3's
5939                if ($handler == 'odeo')
5940                {
5941                        if ($native)
5942                        {
5943                                $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>';
5944                        }
5945                        else
5946                        {
5947                                $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
5948                        }
5949                }
5950
5951                // Flash
5952                elseif ($handler == 'flash')
5953                {
5954                        if ($native)
5955                        {
5956                                $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>";
5957                        }
5958                        else
5959                        {
5960                                $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
5961                        }
5962                }
5963
5964                // Flash Media Player file types.
5965                // Preferred handler for MP3 file types.
5966                elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
5967                {
5968                        $height += 20;
5969                        if ($native)
5970                        {
5971                                $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>";
5972                        }
5973                        else
5974                        {
5975                                $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
5976                        }
5977                }
5978
5979                // QuickTime 7 file types.  Need to test with QuickTime 6.
5980                // Only handle MP3's if the Flash Media Player is not present.
5981                elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
5982                {
5983                        $height += 16;
5984                        if ($native)
5985                        {
5986                                if ($placeholder != ""){
5987                                        $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>";
5988                                }
5989                                else {
5990                                        $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>";
5991                                }
5992                        }
5993                        else
5994                        {
5995                                $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
5996                        }
5997                }
5998
5999                // Windows Media
6000                elseif ($handler == 'wmedia')
6001                {
6002                        $height += 45;
6003                        if ($native)
6004                        {
6005                                $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>";
6006                        }
6007                        else
6008                        {
6009                                $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
6010                        }
6011                }
6012
6013                // Everything else
6014                else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
6015
6016                return $embed;
6017        }
6018
6019        function get_real_type($find_handler = false)
6020        {
6021                // If it's Odeo, let's get it out of the way.
6022                if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
6023                {
6024                        return 'odeo';
6025                }
6026
6027                // Mime-types by handler.
6028                $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
6029                $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
6030                $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
6031                $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
6032                $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
6033
6034                if ($this->get_type() !== null)
6035                {
6036                        $type = strtolower($this->type);
6037                }
6038                else
6039                {
6040                        $type = null;
6041                }
6042
6043                // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
6044                if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
6045                {
6046                        switch (strtolower($this->get_extension()))
6047                        {
6048                                // Audio mime-types
6049                                case 'aac':
6050                                case 'adts':
6051                                        $type = 'audio/acc';
6052                                        break;
6053
6054                                case 'aif':
6055                                case 'aifc':
6056                                case 'aiff':
6057                                case 'cdda':
6058                                        $type = 'audio/aiff';
6059                                        break;
6060
6061                                case 'bwf':
6062                                        $type = 'audio/wav';
6063                                        break;
6064
6065                                case 'kar':
6066                                case 'mid':
6067                                case 'midi':
6068                                case 'smf':
6069                                        $type = 'audio/midi';
6070                                        break;
6071
6072                                case 'm4a':
6073                                        $type = 'audio/x-m4a';
6074                                        break;
6075
6076                                case 'mp3':
6077                                case 'swa':
6078                                        $type = 'audio/mp3';
6079                                        break;
6080
6081                                case 'wav':
6082                                        $type = 'audio/wav';
6083                                        break;
6084
6085                                case 'wax':
6086                                        $type = 'audio/x-ms-wax';
6087                                        break;
6088
6089                                case 'wma':
6090                                        $type = 'audio/x-ms-wma';
6091                                        break;
6092
6093                                // Video mime-types
6094                                case '3gp':
6095                                case '3gpp':
6096                                        $type = 'video/3gpp';
6097                                        break;
6098
6099                                case '3g2':
6100                                case '3gp2':
6101                                        $type = 'video/3gpp2';
6102                                        break;
6103
6104                                case 'asf':
6105                                        $type = 'video/x-ms-asf';
6106                                        break;
6107
6108                                case 'flv':
6109                                        $type = 'video/x-flv';
6110                                        break;
6111
6112                                case 'm1a':
6113                                case 'm1s':
6114                                case 'm1v':
6115                                case 'm15':
6116                                case 'm75':
6117                                case 'mp2':
6118                                case 'mpa':
6119                                case 'mpeg':
6120                                case 'mpg':
6121                                case 'mpm':
6122                                case 'mpv':
6123                                        $type = 'video/mpeg';
6124                                        break;
6125
6126                                case 'm4v':
6127                                        $type = 'video/x-m4v';
6128                                        break;
6129
6130                                case 'mov':
6131                                case 'qt':
6132                                        $type = 'video/quicktime';
6133                                        break;
6134
6135                                case 'mp4':
6136                                case 'mpg4':
6137                                        $type = 'video/mp4';
6138                                        break;
6139
6140                                case 'sdv':
6141                                        $type = 'video/sd-video';
6142                                        break;
6143
6144                                case 'wm':
6145                                        $type = 'video/x-ms-wm';
6146                                        break;
6147
6148                                case 'wmv':
6149                                        $type = 'video/x-ms-wmv';
6150                                        break;
6151
6152                                case 'wvx':
6153                                        $type = 'video/x-ms-wvx';
6154                                        break;
6155
6156                                // Flash mime-types
6157                                case 'spl':
6158                                        $type = 'application/futuresplash';
6159                                        break;
6160
6161                                case 'swf':
6162                                        $type = 'application/x-shockwave-flash';
6163                                        break;
6164                        }
6165                }
6166
6167                if ($find_handler)
6168                {
6169                        if (in_array($type, $types_flash))
6170                        {
6171                                return 'flash';
6172                        }
6173                        elseif (in_array($type, $types_fmedia))
6174                        {
6175                                return 'fmedia';
6176                        }
6177                        elseif (in_array($type, $types_quicktime))
6178                        {
6179                                return 'quicktime';
6180                        }
6181                        elseif (in_array($type, $types_wmedia))
6182                        {
6183                                return 'wmedia';
6184                        }
6185                        elseif (in_array($type, $types_mp3))
6186                        {
6187                                return 'mp3';
6188                        }
6189                        else
6190                        {
6191                                return null;
6192                        }
6193                }
6194                else
6195                {
6196                        return $type;
6197                }
6198        }
6199}
6200
6201class SimplePie_Caption
6202{
6203        var $type;
6204        var $lang;
6205        var $startTime;
6206        var $endTime;
6207        var $text;
6208
6209        // Constructor, used to input the data
6210        function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
6211        {
6212                $this->type = $type;
6213                $this->lang = $lang;
6214                $this->startTime = $startTime;
6215                $this->endTime = $endTime;
6216                $this->text = $text;
6217        }
6218
6219        function __toString()
6220        {
6221                // There is no $this->data here
6222                return md5(serialize($this));
6223        }
6224
6225        function get_endtime()
6226        {
6227                if ($this->endTime !== null)
6228                {
6229                        return $this->endTime;
6230                }
6231                else
6232                {
6233                        return null;
6234                }
6235        }
6236
6237        function get_language()
6238        {
6239                if ($this->language !== null)
6240                {
6241                        return $this->language;
6242                }
6243                else
6244                {
6245                        return null;
6246                }
6247        }
6248
6249        function get_starttime()
6250        {
6251                if ($this->startTime !== null)
6252                {
6253                        return $this->startTime;
6254                }
6255                else
6256                {
6257                        return null;
6258                }
6259        }
6260
6261        function get_text()
6262        {
6263                if ($this->text !== null)
6264                {
6265                        return $this->text;
6266                }
6267                else
6268                {
6269                        return null;
6270                }
6271        }
6272
6273        function get_type()
6274        {
6275                if ($this->type !== null)
6276                {
6277                        return $this->type;
6278                }
6279                else
6280                {
6281                        return null;
6282                }
6283        }
6284}
6285
6286class SimplePie_Credit
6287{
6288        var $role;
6289        var $scheme;
6290        var $name;
6291
6292        // Constructor, used to input the data
6293        function SimplePie_Credit($role = null, $scheme = null, $name = null)
6294        {
6295                $this->role = $role;
6296                $this->scheme = $scheme;
6297                $this->name = $name;
6298        }
6299
6300        function __toString()
6301        {
6302                // There is no $this->data here
6303                return md5(serialize($this));
6304        }
6305
6306        function get_role()
6307        {
6308                if ($this->role !== null)
6309                {
6310                        return $this->role;
6311                }
6312                else
6313                {
6314                        return null;
6315                }
6316        }
6317
6318        function get_scheme()
6319        {
6320                if ($this->scheme !== null)
6321                {
6322                        return $this->scheme;
6323                }
6324                else
6325                {
6326                        return null;
6327                }
6328        }
6329
6330        function get_name()
6331        {
6332                if ($this->name !== null)
6333                {
6334                        return $this->name;
6335                }
6336                else
6337                {
6338                        return null;
6339                }
6340        }
6341}
6342
6343class SimplePie_Copyright
6344{
6345        var $url;
6346        var $label;
6347
6348        // Constructor, used to input the data
6349        function SimplePie_Copyright($url = null, $label = null)
6350        {
6351                $this->url = $url;
6352                $this->label = $label;
6353        }
6354
6355        function __toString()
6356        {
6357                // There is no $this->data here
6358                return md5(serialize($this));
6359        }
6360
6361        function get_url()
6362        {
6363                if ($this->url !== null)
6364                {
6365                        return $this->url;
6366                }
6367                else
6368                {
6369                        return null;
6370                }
6371        }
6372
6373        function get_attribution()
6374        {
6375                if ($this->label !== null)
6376                {
6377                        return $this->label;
6378                }
6379                else
6380                {
6381                        return null;
6382                }
6383        }
6384}
6385
6386class SimplePie_Rating
6387{
6388        var $scheme;
6389        var $value;
6390
6391        // Constructor, used to input the data
6392        function SimplePie_Rating($scheme = null, $value = null)
6393        {
6394                $this->scheme = $scheme;
6395                $this->value = $value;
6396        }
6397
6398        function __toString()
6399        {
6400                // There is no $this->data here
6401                return md5(serialize($this));
6402        }
6403
6404        function get_scheme()
6405        {
6406                if ($this->scheme !== null)
6407                {
6408                        return $this->scheme;
6409                }
6410                else
6411                {
6412                        return null;
6413                }
6414        }
6415
6416        function get_value()
6417        {
6418                if ($this->value !== null)
6419                {
6420                        return $this->value;
6421                }
6422                else
6423                {
6424                        return null;
6425                }
6426        }
6427}
6428
6429class SimplePie_Restriction
6430{
6431        var $relationship;
6432        var $type;
6433        var $value;
6434
6435        // Constructor, used to input the data
6436        function SimplePie_Restriction($relationship = null, $type = null, $value = null)
6437        {
6438                $this->relationship = $relationship;
6439                $this->type = $type;
6440                $this->value = $value;
6441        }
6442
6443        function __toString()
6444        {
6445                // There is no $this->data here
6446                return md5(serialize($this));
6447        }
6448
6449        function get_relationship()
6450        {
6451                if ($this->relationship !== null)
6452                {
6453                        return $this->relationship;
6454                }
6455                else
6456                {
6457                        return null;
6458                }
6459        }
6460
6461        function get_type()
6462        {
6463                if ($this->type !== null)
6464                {
6465                        return $this->type;
6466                }
6467                else
6468                {
6469                        return null;
6470                }
6471        }
6472
6473        function get_value()
6474        {
6475                if ($this->value !== null)
6476                {
6477                        return $this->value;
6478                }
6479                else
6480                {
6481                        return null;
6482                }
6483        }
6484}
6485
6486/**
6487 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
6488 */
6489class SimplePie_File
6490{
6491        var $url;
6492        var $useragent;
6493        var $success = true;
6494        var $headers = array();
6495        var $body;
6496        var $status_code;
6497        var $redirects = 0;
6498        var $error;
6499        var $method;
6500
6501        function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
6502        {
6503                if (class_exists('idna_convert'))
6504                {
6505                        $idn =& new idna_convert;
6506                        $parsed = SimplePie_Misc::parse_url($url);
6507                        $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6508                }
6509                $this->url = $url;
6510                $this->useragent = $useragent;
6511                if (preg_match('/^http(s)?:\/\//i', $url))
6512                {
6513                        if ($useragent === null)
6514                        {
6515                                $useragent = ini_get('user_agent');
6516                                $this->useragent = $useragent;
6517                        }
6518                        if (!is_array($headers))
6519                        {
6520                                $headers = array();
6521                        }
6522                        if (!$force_fsockopen && extension_loaded('curl'))
6523                        {
6524                                $this->method = 'curl';
6525                                $fp = curl_init();
6526                                $headers2 = array();
6527                                foreach ($headers as $key => $value)
6528                                {
6529                                        $headers2[] = "$key: $value";
6530                                }
6531                                if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
6532                                {
6533                                        curl_setopt($fp, CURLOPT_ENCODING, '');
6534                                }
6535                                curl_setopt($fp, CURLOPT_URL, $url);
6536                                curl_setopt($fp, CURLOPT_HEADER, 1);
6537                                curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
6538                                curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
6539                                curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
6540                                curl_setopt($fp, CURLOPT_REFERER, $url);
6541                                curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
6542                                curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
6543                                if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
6544                                {
6545                                        curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
6546                                        curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
6547                                }
6548
6549                                $this->headers = curl_exec($fp);
6550                                if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
6551                                {
6552                                        curl_setopt($fp, CURLOPT_ENCODING, 'none');
6553                                        $this->headers = curl_exec($fp);
6554                                }
6555                                if (curl_errno($fp))
6556                                {
6557                                        $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
6558                                        $this->success = false;
6559                                }
6560                                else
6561                                {
6562                                        $info = curl_getinfo($fp);
6563                                        curl_close($fp);
6564                                        $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
6565                                        $this->headers = array_pop($this->headers);
6566                                        $parser =& new SimplePie_HTTP_Parser($this->headers);
6567                                        if ($parser->parse())
6568                                        {
6569                                                $this->headers = $parser->headers;
6570                                                $this->body = $parser->body;
6571                                                $this->status_code = $parser->status_code;
6572                                                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)
6573                                                {
6574                                                        $this->redirects++;
6575                                                        if (isset($this->headers['content-location']))
6576                                                        {
6577                                                                $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6578                                                        }
6579                                                        else
6580                                                        {
6581                                                                $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6582                                                        }
6583                                                        return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6584                                                }
6585                                        }
6586                                }
6587                        }
6588                        else
6589                        {
6590                                $this->method = 'fsockopen';
6591                                $url_parts = parse_url($url);
6592                                if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
6593                                {
6594                                        $url_parts['host'] = "ssl://$url_parts[host]";
6595                                        $url_parts['port'] = 443;
6596                                }
6597                                if (!isset($url_parts['port']))
6598                                {
6599                                        $url_parts['port'] = 80;
6600                                }
6601                                $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
6602                                if (!$fp)
6603                                {
6604                                        $this->error = 'fsockopen error: ' . $errstr;
6605                                        $this->success = false;
6606                                }
6607                                else
6608                                {
6609                                        if (function_exists('stream_set_timeout'))
6610                                        {
6611                                                stream_set_timeout($fp, $timeout);
6612                                        }
6613                                        else
6614                                        {
6615                                                socket_set_timeout($fp, $timeout);
6616                                        }
6617                                        if (isset($url_parts['path']))
6618                                        {
6619                                                if (isset($url_parts['query']))
6620                                                {
6621                                                        $get = "$url_parts[path]?$url_parts[query]";
6622                                                }
6623                                                else
6624                                                {
6625                                                        $get = $url_parts['path'];
6626                                                }
6627                                        }
6628                                        else
6629                                        {
6630                                                $get = '/';
6631                                        }
6632                                        $out = "GET $get HTTP/1.0\r\n";
6633                                        $out .= "Host: $url_parts[host]\r\n";
6634                                        $out .= "User-Agent: $useragent\r\n";
6635                                        if (function_exists('gzinflate'))
6636                                        {
6637                                                $out .= "Accept-Encoding: gzip,deflate\r\n";
6638                                        }
6639
6640                                        if (isset($url_parts['user']) && isset($url_parts['pass']))
6641                                        {
6642                                                $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
6643                                        }
6644                                        foreach ($headers as $key => $value)
6645                                        {
6646                                                $out .= "$key: $value\r\n";
6647                                        }
6648                                        $out .= "Connection: Close\r\n\r\n";
6649                                        fwrite($fp, $out);
6650
6651                                        if (function_exists('stream_get_meta_data'))
6652                                        {
6653                                                $info = stream_get_meta_data($fp);
6654                                        }
6655                                        else
6656                                        {
6657                                                $info = socket_get_status($fp);
6658                                        }
6659
6660                                        $this->headers = '';
6661                                        while (!$info['eof'] && !$info['timed_out'])
6662                                        {
6663                                                $this->headers .= fread($fp, 1160);
6664                                                if (function_exists('stream_get_meta_data'))
6665                                                {
6666                                                        $info = stream_get_meta_data($fp);
6667                                                }
6668                                                else
6669                                                {
6670                                                        $info = socket_get_status($fp);
6671                                                }
6672                                        }
6673                                        if (!$info['timed_out'])
6674                                        {
6675                                                $parser =& new SimplePie_HTTP_Parser($this->headers);
6676                                                if ($parser->parse())
6677                                                {
6678                                                        $this->headers = $parser->headers;
6679                                                        $this->body = $parser->body;
6680                                                        $this->status_code = $parser->status_code;
6681                                                        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)
6682                                                        {
6683                                                                $this->redirects++;
6684                                                                if (isset($this->headers['content-location']))
6685                                                                {
6686                                                                        $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6687                                                                }
6688                                                                else
6689                                                                {
6690                                                                        $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6691                                                                }
6692                                                                return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6693                                                        }
6694                                                        if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
6695                                                        {
6696                                                                if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
6697                                                                {
6698                                                                        $this->body = substr($this->body, 10);
6699                                                                }
6700                                                                $this->body = gzinflate($this->body);
6701                                                        }
6702                                                }
6703                                        }
6704                                        else
6705                                        {
6706                                                $this->error = 'fsocket timed out';
6707                                                $this->success = false;
6708                                        }
6709                                        fclose($fp);
6710                                }
6711                        }
6712                }
6713                elseif (function_exists('file_get_contents'))
6714                {
6715                        $this->method = 'file_get_contents';
6716                        if (!$this->body = file_get_contents($url))
6717                        {
6718                                $this->error = 'file_get_contents could not read the file';
6719                                $this->success = false;
6720                        }
6721                }
6722                else
6723                {
6724                        $this->method = 'fopen';
6725                        if (($fp = fopen($url, 'rb')) === false)
6726                        {
6727                                $this->error = 'failed to open stream: No such file or directory';
6728                                $this->success = false;
6729                        }
6730                        else
6731                        {
6732                                $this->body = '';
6733                                while (!feof($fp))
6734                                {
6735                                        $this->body .= fread($fp, 8192);
6736                                }
6737                                fclose($fp);
6738                        }
6739                }
6740        }
6741}
6742
6743/**
6744 * HTTP Response Parser
6745 *
6746 * @package SimplePie
6747 * @todo Support HTTP Requests
6748 */
6749class SimplePie_HTTP_Parser
6750{
6751        /**
6752         * HTTP Version
6753         *
6754         * @access public
6755         * @var string
6756         */
6757        var $http_version = '';
6758
6759        /**
6760         * Status code
6761         *
6762         * @access public
6763         * @var string
6764         */
6765        var $status_code = '';
6766
6767        /**
6768         * Reason phrase
6769         *
6770         * @access public
6771         * @var string
6772         */
6773        var $reason = '';
6774
6775        /**
6776         * Key/value pairs of the headers
6777         *
6778         * @access public
6779         * @var array
6780         */
6781        var $headers = array();
6782
6783        /**
6784         * Body of the response
6785         *
6786         * @access public
6787         * @var string
6788         */
6789        var $body = '';
6790
6791        /**
6792         * Current state of the state machine
6793         *
6794         * @access private
6795         * @var string
6796         */
6797        var $state = 'start';
6798
6799        /**
6800         * Input data
6801         *
6802         * @access private
6803         * @var string
6804         */
6805        var $data = '';
6806
6807        /**
6808         * Input data length (to avoid calling strlen() everytime this is needed)
6809         *
6810         * @access private
6811         * @var int
6812         */
6813        var $data_length = 0;
6814
6815        /**
6816         * Current position of the pointer
6817         *
6818         * @access private
6819         * @var int
6820         */
6821        var $position = 0;
6822
6823        /**
6824         * Name of the hedaer currently being parsed
6825         *
6826         * @access private
6827         * @var string
6828         */
6829        var $name = '';
6830
6831        /**
6832         * Value of the hedaer currently being parsed
6833         *
6834         * @access private
6835         * @var string
6836         */
6837        var $value = '';
6838
6839        /**
6840         * Create an instance of the class with the input data
6841         *
6842         * @access public
6843         * @param string $data Input data
6844         */
6845        function SimplePie_HTTP_Parser($data)
6846        {
6847                $this->data = $data;
6848                $this->data_length = strlen($this->data);
6849        }
6850
6851        /**
6852         * Parse the input data
6853         *
6854         * @access public
6855         * @return bool true on success, false on failure
6856         */
6857        function parse()
6858        {
6859                while ($this->state && $this->state != 'emit' && $this->has_data())
6860                {
6861                        $state = $this->state;
6862                        $this->$state();
6863                }
6864                $this->data = '';
6865                if ($this->state == 'emit')
6866                {
6867                        return true;
6868                }
6869                else
6870                {
6871                        $this->http_version = '';
6872                        $this->status_code = '';
6873                        $this->headers = array();
6874                        $this->body = '';
6875                        return false;
6876                }
6877        }
6878
6879        /**
6880         * Check whether there is data beyond the pointer
6881         *
6882         * @access private
6883         * @return bool true if there is further data, false if not
6884         */
6885        function has_data()
6886        {
6887                return (bool) ($this->position < $this->data_length);
6888        }
6889
6890        /**
6891         * See if the next character is LWS
6892         *
6893         * @access private
6894         * @return bool true if the next character is LWS, false if not
6895         */
6896        function is_linear_whitespace()
6897        {
6898                return (bool) (strspn($this->data, "\x09\x20", $this->position, 1)
6899                        || (substr($this->data, $this->position, 2) == "\r\n" && strspn($this->data, "\x09\x20", $this->position + 2, 1))
6900                        || (strspn($this->data, "\r\n", $this->position, 1) && strspn($this->data, "\x09\x20", $this->position + 1, 1)));
6901        }
6902
6903        /**
6904         * The starting state of the state machine, see if the data is a response or request
6905         *
6906         * @access private
6907         */
6908        function start()
6909        {
6910                $this->state = 'http_version_response';
6911        }
6912
6913        /**
6914         * Parse an HTTP-version string
6915         *
6916         * @access private
6917         */
6918        function http_version()
6919        {
6920                if (preg_match('/^HTTP\/([0-9]+\.[0-9]+)/i', substr($this->data, $this->position, strcspn($this->data, "\r\n", $this->position)), $match))
6921                {
6922                        $this->position += strlen($match[0]);
6923                        $this->http_version = $match[1];
6924                        return true;
6925                }
6926                else
6927                {
6928                        return false;
6929                }
6930        }
6931
6932        /**
6933         * Parse LWS, replacing consecutive characters with a single space
6934         *
6935         * @access private
6936         */
6937        function linear_whitespace()
6938        {
6939                do
6940                {
6941                        if (substr($this->data, $this->position, 2) == "\r\n")
6942                        {
6943                                $this->position += 2;
6944                        }
6945                        elseif (strspn($this->data, "\r\n", $this->position, 1))
6946                        {
6947                                $this->position++;
6948                        }
6949                        $this->position += strspn($this->data, "\x09\x20", $this->position);
6950                } while ($this->is_linear_whitespace());
6951                $this->value .= "\x20";
6952        }
6953
6954        /**
6955         * Parse an HTTP-version string within a response
6956         *
6957         * @access private
6958         */
6959        function http_version_response()
6960        {
6961                if ($this->http_version() && $this->data[$this->position] == "\x20")
6962                {
6963                        $this->state = 'status_code';
6964                        $this->position++;
6965                }
6966                else
6967                {
6968                        $this->state = false;
6969                }
6970        }
6971
6972        /**
6973         * Parse a status code
6974         *
6975         * @access private
6976         */
6977        function status_code()
6978        {
6979                if (strspn($this->data, '1234567890', $this->position, 3) == 3)
6980                {
6981                        $this->status_code = substr($this->data, $this->position, 3);
6982                        $this->state = 'reason_phrase';
6983                        $this->position += 3;
6984                }
6985                else
6986                {
6987                        $this->state = false;
6988                }
6989        }
6990
6991        /**
6992         * Skip over the reason phrase (it has no normative value, and you can send absolutely anything here)
6993         *
6994         * @access private
6995         */
6996        function reason_phrase()
6997        {
6998                $len = strcspn($this->data, "\r\n", $this->position);
6999                $this->reason = substr($this->data, $this->position, $len);
7000                $this->position += $len;
7001                if ($this->has_data())
7002                {
7003                        if (substr($this->data, $this->position, 2) == "\r\n")
7004                        {
7005                                $this->position += 2;
7006                        }
7007                        elseif (strspn($this->data, "\r\n", $this->position, 1))
7008                        {
7009                                $this->position++;
7010                        }
7011                        $this->state = 'name';
7012                }
7013        }
7014
7015        /**
7016         * Parse a header name
7017         *
7018         * @access private
7019         */
7020        function name()
7021        {
7022                $len = strcspn($this->data, ':', $this->position);
7023                $this->name = substr($this->data, $this->position, $len);
7024                $this->position += $len;
7025
7026                if ($this->has_data() && $this->data[$this->position] == ':')
7027                {
7028                        $this->state = 'value_next';
7029                        $this->position++;
7030                }
7031                else
7032                {
7033                        $this->state = false;
7034                }
7035        }
7036
7037        /**
7038         * See what state to move the state machine to while within non-quoted header values
7039         *
7040         * @access private
7041         */
7042        function value_next()
7043        {
7044                if ($this->is_linear_whitespace())
7045                {
7046                        $this->state = 'value_linear_whitespace';
7047                }
7048                elseif ($this->data[$this->position] == '"')
7049                {
7050                        $this->state = 'value_quote_next';
7051                        $this->position++;
7052                }
7053                elseif (substr($this->data, $this->position, 2) == "\r\n")
7054                {
7055                        $this->state = 'end_crlf';
7056                        $this->position += 2;
7057                }
7058                elseif (strspn($this->data, "\r\n", $this->position, 1))
7059                {
7060                        $this->state = 'end_crlf';
7061                        $this->position++;
7062                }
7063                else
7064                {
7065                        $this->state = 'value_no_quote';
7066                }
7067        }
7068
7069        /**
7070         * Parse a header value while outside quotes
7071         *
7072         * @access private
7073         */
7074        function value_no_quote()
7075        {
7076                $len = strcspn($this->data, "\x09\x20\r\n\"", $this->position);
7077                $this->value .= substr($this->data, $this->position, $len);
7078                $this->state = 'value_next';
7079                $this->position += $len;
7080        }
7081
7082        /**
7083         * Parse LWS outside quotes
7084         *
7085         * @access private
7086         */
7087        function value_linear_whitespace()
7088        {
7089                $this->linear_whitespace();
7090                $this->state = 'value_next';
7091        }
7092
7093        /**
7094         * See what state to move the state machine to while within quoted header values
7095         *
7096         * @access private
7097         */
7098        function value_quote_next()
7099        {
7100                if ($this->is_linear_whitespace())
7101                {
7102                        $this->state = 'value_linear_whitespace_quote';
7103                }
7104                else
7105                {
7106                        switch ($this->data[$this->position])
7107                        {
7108                                case '"':
7109                                        $this->state = 'value_next';
7110                                        $this->position++;
7111                                        break;
7112
7113                                case '\\':
7114                                        $this->state = 'value_quote_char';
7115                                        $this->position++;
7116                                        break;
7117
7118                                default:
7119                                        $this->state = 'value_quote';
7120                                        break;
7121                        }
7122                }
7123        }
7124
7125        /**
7126         * Parse a header value while within quotes
7127         *
7128         * @access private
7129         */
7130        function value_quote()
7131        {
7132                $len = strcspn($this->data, "\x09\x20\r\n\"\\", $this->position);
7133                $this->value .= substr($this->data, $this->position, $len);
7134                $this->position += $len;
7135                $this->state = 'value_quote_next';
7136        }
7137
7138        /**
7139         * Parse an escaped character within quotes
7140         *
7141         * @access private
7142         */
7143        function value_quote_char()
7144        {
7145                $this->value .= $this->data[$this->position];
7146                $this->state = 'value_quote_next';
7147                $this->position++;
7148        }
7149
7150        /**
7151         * Parse LWS within quotes
7152         *
7153         * @access private
7154         */
7155        function value_linear_whitespace_quote()
7156        {
7157                $this->linear_whitespace();
7158                $this->state = 'value_quote_next';
7159        }
7160
7161        /**
7162         * Parse a CRLF, and see whether we have a further header, or whether we are followed by the body
7163         *
7164         * @access private
7165         */
7166        function end_crlf()
7167        {
7168                $this->name = strtolower($this->name);
7169                $this->value = trim($this->value, "\x20");
7170                if (isset($this->headers[$this->name]))
7171                {
7172                        $this->headers[$this->name] .= ', ' . $this->value;
7173                }
7174                else
7175                {
7176                        $this->headers[$this->name] = $this->value;
7177                }
7178
7179                if (substr($this->data, $this->position, 2) == "\r\n")
7180                {
7181                        $this->body = substr($this->data, $this->position + 2);
7182                        $this->state = 'emit';
7183                }
7184                elseif (strspn($this->data, "\r\n", $this->position, 1))
7185                {
7186                        $this->body = substr($this->data, $this->position + 1);
7187                        $this->state = 'emit';
7188                }
7189                else
7190                {
7191                        $this->name = '';
7192                        $this->value = '';
7193                        $this->state = 'name';
7194                }
7195        }
7196}
7197
7198class SimplePie_Cache
7199{
7200        var $location;
7201        var $filename;
7202        var $extension;
7203        var $name;
7204
7205        function SimplePie_Cache($location, $filename, $extension)
7206        {
7207                $this->location = $location;
7208                $this->filename = rawurlencode($filename);
7209                $this->extension = rawurlencode($extension);
7210                $this->name = "$location/$this->filename.$this->extension";
7211        }
7212
7213        function save($data)
7214        {
7215                if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
7216                {
7217                        if (function_exists('file_put_contents'))
7218                        {
7219                                return (bool) file_put_contents($this->name, serialize($data));
7220                        }
7221                        else
7222                        {
7223                                $fp = fopen($this->name, 'wb');
7224                                if ($fp)
7225                                {
7226                                        fwrite($fp, serialize($data));
7227                                        fclose($fp);
7228                                        return true;
7229                                }
7230                        }
7231                }
7232                return false;
7233        }
7234
7235        function load()
7236        {
7237                if (file_exists($this->name) && is_readable($this->name))
7238                {
7239                        if (function_exists('file_get_contents'))
7240                        {
7241                                return unserialize(file_get_contents($this->name));
7242                        }
7243                        elseif (($fp = fopen($this->name, 'rb')) !== false)
7244                        {
7245                                $data = '';
7246                                while (!feof($fp))
7247                                {
7248                                        $data .= fread($fp, 8192);
7249                                }
7250                                fclose($fp);
7251                                return unserialize($data);
7252                        }
7253                }
7254                return false;
7255        }
7256
7257        function mtime()
7258        {
7259                if (file_exists($this->name))
7260                {
7261                        return filemtime($this->name);
7262                }
7263                return false;
7264        }
7265
7266        function touch()
7267        {
7268                if (file_exists($this->name))
7269                {
7270                        return touch($this->name);
7271                }
7272                return false;
7273        }
7274
7275        function unlink()
7276        {
7277                if (file_exists($this->name))
7278                {
7279                        return unlink($this->name);
7280                }
7281                return false;
7282        }
7283}
7284
7285class SimplePie_Misc
7286{
7287        function time_hms($seconds)
7288        {
7289                $time = '';
7290
7291                $hours = floor($seconds / 3600);
7292                $remainder = $seconds % 3600;
7293                if ($hours > 0)
7294                {
7295                        $time .= $hours.':';
7296                }
7297
7298                $minutes = floor($remainder / 60);
7299                $seconds = $remainder % 60;
7300                if ($minutes < 10 && $hours > 0)
7301                {
7302                        $minutes = '0' . $minutes;
7303                }
7304                if ($seconds < 10)
7305                {
7306                        $seconds = '0' . $seconds;
7307                }
7308
7309                $time .= $minutes.':';
7310                $time .= $seconds;
7311
7312                return $time;
7313        }
7314
7315        function absolutize_url($relative, $base)
7316        {
7317                if ($relative !== '')
7318                {
7319                        $relative = SimplePie_Misc::parse_url($relative);
7320                        if ($relative['scheme'] !== '')
7321                        {
7322                                $target = $relative;
7323                        }
7324                        elseif ($base !== '')
7325                        {
7326                                $base = SimplePie_Misc::parse_url($base);
7327                                $target = SimplePie_Misc::parse_url('');
7328                                if ($relative['authority'] !== '')
7329                                {
7330                                        $target = $relative;
7331                                        $target['scheme'] = $base['scheme'];
7332                                }
7333                                else
7334                                {
7335                                        $target['scheme'] = $base['scheme'];
7336                                        $target['authority'] = $base['authority'];
7337                                        if ($relative['path'] !== '')
7338                                        {
7339                                                if (strpos($relative['path'], '/') === 0)
7340                                                {
7341                                                        $target['path'] = $relative['path'];
7342                                                }
7343                                                elseif (($target['path'] = dirname("$base[path].")) == '/')
7344                                                {
7345                                                        $target['path'] .= $relative['path'];
7346                                                }
7347                                                else
7348                                                {
7349                                                        $target['path'] .= '/' . $relative['path'];
7350                                                }
7351                                                if ($relative['query'] !== '')
7352                                                {
7353                                                        $target['query'] = $relative['query'];
7354                                                }
7355                                        }
7356                                        else
7357                                        {
7358                                                if ($base['path'] !== '')
7359                                                {
7360                                                        $target['path'] = $base['path'];
7361                                                }
7362                                                else
7363                                                {
7364                                                        $target['path'] = '/';
7365                                                }
7366                                                if ($relative['query'] !== '')
7367                                                {
7368                                                        $target['query'] = $relative['query'];
7369                                                }
7370                                                elseif ($base['query'] !== '')
7371                                                {
7372                                                        $target['query'] = $base['query'];
7373                                                }
7374                                        }
7375                                }
7376                                if ($relative['fragment'] !== '')
7377                                {
7378                                        $target['fragment'] = $relative['fragment'];
7379                                }
7380                        }
7381                        else
7382                        {
7383                                // No base URL, just return the relative URL
7384                                $target = $relative;
7385                        }
7386                        $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
7387                }
7388                else
7389                {
7390                        $return = $base;
7391                }
7392                $return = SimplePie_Misc::normalize_url($return);
7393                return $return;
7394        }
7395
7396        function remove_dot_segments($input)
7397        {
7398                $output = '';
7399                while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
7400                {
7401                        // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
7402                        if (strpos($input, '../') === 0)
7403                        {
7404                                $input = substr($input, 3);
7405                        }
7406                        elseif (strpos($input, './') === 0)
7407                        {
7408                                $input = substr($input, 2);
7409                        }
7410                        // 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,
7411                        elseif (strpos($input, '/./') === 0)
7412                        {
7413                                $input = substr_replace($input, '/', 0, 3);
7414                        }
7415                        elseif ($input == '/.')
7416                        {
7417                                $input = '/';
7418                        }
7419                        // 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,
7420                        elseif (strpos($input, '/../') === 0)
7421                        {
7422                                $input = substr_replace($input, '/', 0, 4);
7423                                $output = substr_replace($output, '', strrpos($output, '/'));
7424                        }
7425                        elseif ($input == '/..')
7426                        {
7427                                $input = '/';
7428                                $output = substr_replace($output, '', strrpos($output, '/'));
7429                        }
7430                        // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
7431                        elseif ($input == '.' || $input == '..')
7432                        {
7433                                $input = '';
7434                        }
7435                        // 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
7436                        elseif (($pos = strpos($input, '/', 1)) !== false)
7437                        {
7438                                $output .= substr($input, 0, $pos);
7439                                $input = substr_replace($input, '', 0, $pos);
7440                        }
7441                        else
7442                        {
7443                                $output .= $input;
7444                                $input = '';
7445                        }
7446                }
7447                return $output . $input;
7448        }
7449
7450        function get_element($realname, $string)
7451        {
7452                $return = array();
7453                $name = preg_quote($realname, '/');
7454                if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
7455                {
7456                        for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
7457                        {
7458                                $return[$i]['tag'] = $realname;
7459                                $return[$i]['full'] = $matches[$i][0][0];
7460                                $return[$i]['offset'] = $matches[$i][0][1];
7461                                if (strlen($matches[$i][3][0]) <= 2)
7462                                {
7463                                        $return[$i]['self_closing'] = true;
7464                                }
7465                                else
7466                                {
7467                                        $return[$i]['self_closing'] = false;
7468                                        $return[$i]['content'] = $matches[$i][4][0];
7469                                }
7470                                $return[$i]['attribs'] = array();
7471                                if (isset($matches[$i][2][0]) && preg_match_all('/((?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([a-z0-9\-._:]*)))?\s/U', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
7472                                {
7473                                        for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
7474                                        {
7475                                                if (count($attribs[$j]) == 2)
7476                                                {
7477                                                        $attribs[$j][2] = $attribs[$j][1];
7478                                                }
7479                                                $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
7480                                        }
7481                                }
7482                        }
7483                }
7484                return $return;
7485        }
7486
7487        function element_implode($element)
7488        {
7489                $full = "<$element[tag]";
7490                foreach ($element['attribs'] as $key => $value)
7491                {
7492                        $key = strtolower($key);
7493                        $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
7494                }
7495                if ($element['self_closing'])
7496                {
7497                        $full .= ' />';
7498                }
7499                else
7500                {
7501                        $full .= ">$element[content]</$element[tag]>";
7502                }
7503                return $full;
7504        }
7505
7506        function error($message, $level, $file, $line)
7507        {
7508                switch ($level)
7509                {
7510                        case E_USER_ERROR:
7511                                $note = 'PHP Error';
7512                                break;
7513                        case E_USER_WARNING:
7514                                $note = 'PHP Warning';
7515                                break;
7516                        case E_USER_NOTICE:
7517                                $note = 'PHP Notice';
7518                                break;
7519                        default:
7520                                $note = 'Unknown Error';
7521                                break;
7522                }
7523                error_log("$note: $message in $file on line $line", 0);
7524                return $message;
7525        }
7526
7527        /**
7528         * If a file has been cached, retrieve and display it.
7529         *
7530         * This is most useful for caching images (get_favicon(), etc.),
7531         * however it works for all cached files.  This WILL NOT display ANY
7532         * file/image/page/whatever, but rather only display what has already
7533         * been cached by SimplePie.
7534         *
7535         * @access public
7536         * @see SimplePie::get_favicon()
7537         * @param str $identifier_url URL that is used to identify the content.
7538         * This may or may not be the actual URL of the live content.
7539         * @param str $cache_location Location of SimplePie's cache.  Defaults
7540         * to './cache'.
7541         * @param str $cache_extension The file extension that the file was
7542         * cached with.  Defaults to 'spc'.
7543         * @param str $cache_class Name of the cache-handling class being used
7544         * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
7545         * as-is unless you've overloaded the class.
7546         * @param str $cache_name_function Function that converts the filename
7547         * for saving.  Defaults to 'md5'.
7548         */
7549        function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
7550        {
7551                $cache =& new $cache_class($cache_location, call_user_func($cache_name_function, $identifier_url), $cache_extension);
7552
7553                if ($file = $cache->load())
7554                {
7555                        header('Content-type:' . $file['headers']['content-type']);
7556                        header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
7557                        echo $file['body'];
7558                        exit;
7559                }
7560
7561                die('Cached file for ' . $identifier_url . ' cannot be found.');
7562        }
7563
7564        function fix_protocol($url, $http = 1)
7565        {
7566                $url = SimplePie_Misc::normalize_url($url);
7567                $parsed = SimplePie_Misc::parse_url($url);
7568                if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
7569                {
7570                        return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
7571                }
7572               
7573                if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
7574                {
7575                        return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
7576                }
7577
7578                if ($http == 2 && $parsed['scheme'] !== '')
7579                {
7580                        return "feed:$url";
7581                }
7582                elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
7583                {
7584                        return substr_replace($url, 'podcast', 0, 4);
7585                }
7586                elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
7587                {
7588                        return substr_replace($url, 'itpc', 0, 4);
7589                }
7590                else
7591                {
7592                        return $url;
7593                }
7594        }
7595
7596        function parse_url($url)
7597        {
7598                static $cache = array();
7599                if (isset($cache[$url]))
7600                {
7601                        return $cache[$url];
7602                }
7603                elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
7604                {
7605                        for ($i = count($match); $i <= 9; $i++)
7606                        {
7607                                $match[$i] = '';
7608                        }
7609                        return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
7610                }
7611                else
7612                {
7613                        return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
7614                }
7615        }
7616
7617        function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
7618        {
7619                $return = '';
7620                if ($scheme !== '')
7621                {
7622                        $return .= "$scheme:";
7623                }
7624                if ($authority !== '')
7625                {
7626                        $return .= "//$authority";
7627                }
7628                if ($path !== '')
7629                {
7630                        $return .= $path;
7631                }
7632                if ($query !== '')
7633                {
7634                        $return .= "?$query";
7635                }
7636                if ($fragment !== '')
7637                {
7638                        $return .= "#$fragment";
7639                }
7640                return $return;
7641        }
7642
7643        function normalize_url($url)
7644        {
7645                $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
7646                $url = SimplePie_Misc::parse_url($url);
7647                $url['scheme'] = strtolower($url['scheme']);
7648                if ($url['authority'] !== '')
7649                {
7650                        $url['authority'] = strtolower($url['authority']);
7651                        $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
7652                }
7653                return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
7654        }
7655
7656        function percent_encoding_normalization($match)
7657        {
7658                $integer = hexdec($match[1]);
7659                if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
7660                {
7661                        return chr($integer);
7662                }
7663                else
7664                {
7665                        return strtoupper($match[0]);
7666                }
7667        }
7668
7669        /**
7670         * Remove bad UTF-8 bytes
7671         *
7672         * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
7673         * FAQ: Multilingual Forms (modified to include full ASCII range)
7674         *
7675         * @author Geoffrey Sneddon
7676         * @see http://www.w3.org/International/questions/qa-forms-utf-8
7677         * @param string $str String to remove bad UTF-8 bytes from
7678         * @return string UTF-8 string
7679         */
7680        function utf8_bad_replace($str)
7681        {
7682                if (function_exists('iconv'))
7683                {
7684                        return iconv('UTF-8', 'UTF-8//IGNORE', $str);
7685                }
7686                elseif (function_exists('mb_convert_encoding'))
7687                {
7688                        return mb_convert_encoding($str, 'UTF-8', 'UTF-8');
7689                }
7690                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))
7691                {
7692                        return implode("\xEF\xBF\xBD", $matches[0]);
7693                }
7694                elseif ($str !== '')
7695                {
7696                        return "\xEF\xBF\xBD";
7697                }
7698                else
7699                {
7700                        return '';
7701                }
7702        }
7703
7704        function change_encoding($data, $input, $output)
7705        {
7706                $input = SimplePie_Misc::encoding($input);
7707                $output = SimplePie_Misc::encoding($output);
7708
7709                if (function_exists('iconv') && ($return = @iconv($input, "$output//IGNORE", $data)))
7710                {
7711                        return $return;
7712                }
7713                elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
7714                {
7715                        return $return;
7716                }
7717                elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
7718                {
7719                        return $return;
7720                }
7721                elseif ($input == 'ISO-8859-1' && $output == 'UTF-8')
7722                {
7723                        return utf8_encode($data);
7724                }
7725                elseif ($input == 'UTF-8' && $output == 'ISO-8859-1')
7726                {
7727                        return utf8_decode($data);
7728                }
7729                return $data;
7730        }
7731
7732        function encoding($encoding)
7733        {
7734                // Character sets are case-insensitive (though we'll return them in the form given in their registration)
7735                switch (strtoupper($encoding))
7736                {
7737                        case 'ANSI_X3.4-1968':
7738                        case 'ISO-IR-6':
7739                        case 'ANSI_X3.4-1986':
7740                        case 'ISO_646.IRV:1991':
7741                        case 'ASCII':
7742                        case 'ISO646-US':
7743                        case 'US-ASCII':
7744                        case 'US':
7745                        case 'IBM367':
7746                        case 'CP367':
7747                        case 'CSASCII':
7748                                return 'US-ASCII';
7749
7750                        case 'ISO_8859-1:1987':
7751                        case 'ISO-IR-100':
7752                        case 'ISO_8859-1':
7753                        case 'ISO-8859-1':
7754                        case 'LATIN1':
7755                        case 'L1':
7756                        case 'IBM819':
7757                        case 'CP819':
7758                        case 'CSISOLATIN1':
7759                                return 'ISO-8859-1';
7760
7761                        case 'ISO_8859-2:1987':
7762                        case 'ISO-IR-101':
7763                        case 'ISO_8859-2':
7764                        case 'ISO-8859-2':
7765                        case 'LATIN2':
7766                        case 'L2':
7767                        case 'CSISOLATIN2':
7768                                return 'ISO-8859-2';
7769
7770                        case 'ISO_8859-3:1988':
7771                        case 'ISO-IR-109':
7772                        case 'ISO_8859-3':
7773                        case 'ISO-8859-3':
7774                        case 'LATIN3':
7775                        case 'L3':
7776                        case 'CSISOLATIN3':
7777                                return 'ISO-8859-3';
7778
7779                        case 'ISO_8859-4:1988':
7780                        case 'ISO-IR-110':
7781                        case 'ISO_8859-4':
7782                        case 'ISO-8859-4':
7783                        case 'LATIN4':
7784                        case 'L4':
7785                        case 'CSISOLATIN4':
7786                                return 'ISO-8859-4';
7787
7788                        case 'ISO_8859-5:1988':
7789                        case 'ISO-IR-144':
7790                        case 'ISO_8859-5':
7791                        case 'ISO-8859-5':
7792                        case 'CYRILLIC':
7793                        case 'CSISOLATINCYRILLIC':
7794                                return 'ISO-8859-5';
7795
7796                        case 'ISO_8859-6:1987':
7797                        case 'ISO-IR-127':
7798                        case 'ISO_8859-6':
7799                        case 'ISO-8859-6':
7800                        case 'ECMA-114':
7801                        case 'ASMO-708':
7802                        case 'ARABIC':
7803                        case 'CSISOLATINARABIC':
7804                                return 'ISO-8859-6';
7805
7806                        case 'ISO_8859-7:1987':
7807                        case 'ISO-IR-126':
7808                        case 'ISO_8859-7':
7809                        case 'ISO-8859-7':
7810                        case 'ELOT_928':
7811                        case 'ECMA-118':
7812                        case 'GREEK':
7813                        case 'GREEK8':
7814                        case 'CSISOLATINGREEK':
7815                                return 'ISO-8859-7';
7816
7817                        case 'ISO_8859-8:1988':
7818                        case 'ISO-IR-138':
7819                        case 'ISO_8859-8':
7820                        case 'ISO-8859-8':
7821                        case 'HEBREW':
7822                        case 'CSISOLATINHEBREW':
7823                                return 'ISO-8859-8';
7824
7825                        case 'ISO_8859-9:1989':
7826                        case 'ISO-IR-148':
7827                        case 'ISO_8859-9':
7828                        case 'ISO-8859-9':
7829                        case 'LATIN5':
7830                        case 'L5':
7831                        case 'CSISOLATIN5':
7832                                return 'ISO-8859-9';
7833
7834                        case 'ISO-8859-10':
7835                        case 'ISO-IR-157':
7836                        case 'L6':
7837                        case 'ISO_8859-10:1992':
7838                        case 'CSISOLATIN6':
7839                        case 'LATIN6':
7840                                return 'ISO-8859-10';
7841
7842                        case 'ISO_6937-2-ADD':
7843                        case 'ISO-IR-142':
7844                        case 'CSISOTEXTCOMM':
7845                                return 'ISO_6937-2-add';
7846
7847                        case 'JIS_X0201':
7848                        case 'X0201':
7849                        case 'CSHALFWIDTHKATAKANA':
7850                                return 'JIS_X0201';
7851
7852                        case 'JIS_ENCODING':
7853                        case 'CSJISENCODING':
7854                                return 'JIS_Encoding';
7855
7856                        case 'SHIFT_JIS':
7857                        case 'MS_KANJI':
7858                        case 'CSSHIFTJIS':
7859                                return 'Shift_JIS';
7860
7861                        case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
7862                        case 'CSEUCPKDFMTJAPANESE':
7863                        case 'EUC-JP':
7864                                return 'EUC-JP';
7865
7866                        case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
7867                        case 'CSEUCFIXWIDJAPANESE':
7868                                return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
7869
7870                        case 'BS_4730':
7871                        case 'ISO-IR-4':
7872                        case 'ISO646-GB':
7873                        case 'GB':
7874                        case 'UK':
7875                        case 'CSISO4UNITEDKINGDOM':
7876                                return 'BS_4730';
7877
7878                        case 'SEN_850200_C':
7879                        case 'ISO-IR-11':
7880                        case 'ISO646-SE2':
7881                        case 'SE2':
7882                        case 'CSISO11SWEDISHFORNAMES':
7883                                return 'SEN_850200_C';
7884
7885                        case 'IT':
7886                        case 'ISO-IR-15':
7887                        case 'ISO646-IT':
7888                        case 'CSISO15ITALIAN':
7889                                return 'IT';
7890
7891                        case 'ES':
7892                        case 'ISO-IR-17':
7893                        case 'ISO646-ES':
7894                        case 'CSISO17SPANISH':
7895                                return 'ES';
7896
7897                        case 'DIN_66003':
7898                        case 'ISO-IR-21':
7899                        case 'DE':
7900                        case 'ISO646-DE':
7901                        case 'CSISO21GERMAN':
7902                                return 'DIN_66003';
7903
7904                        case 'NS_4551-1':
7905                        case 'ISO-IR-60':
7906                        case 'ISO646-NO':
7907                        case 'NO':
7908                        case 'CSISO60DANISHNORWEGIAN':
7909                        case 'CSISO60NORWEGIAN1':
7910                                return 'NS_4551-1';
7911
7912                        case 'NF_Z_62-010':
7913                        case 'ISO-IR-69':
7914                        case 'ISO646-FR':
7915                        case 'FR':
7916                        case 'CSISO69FRENCH':
7917                                return 'NF_Z_62-010';
7918
7919                        case 'ISO-10646-UTF-1':
7920                        case 'CSISO10646UTF1':
7921                                return 'ISO-10646-UTF-1';
7922
7923                        case 'ISO_646.BASIC:1983':
7924                        case 'REF':
7925                        case 'CSISO646BASIC1983':
7926                                return 'ISO_646.basic:1983';
7927
7928                        case 'INVARIANT':
7929                        case 'CSINVARIANT':
7930                                return 'INVARIANT';
7931
7932                        case 'ISO_646.IRV:1983':
7933                        case 'ISO-IR-2':
7934                        case 'IRV':
7935                        case 'CSISO2INTLREFVERSION':
7936                                return 'ISO_646.irv:1983';
7937
7938                        case 'NATS-SEFI':
7939                        case 'ISO-IR-8-1':
7940                        case 'CSNATSSEFI':
7941                                return 'NATS-SEFI';
7942
7943                        case 'NATS-SEFI-ADD':
7944                        case 'ISO-IR-8-2':
7945                        case 'CSNATSSEFIADD':
7946                                return 'NATS-SEFI-ADD';
7947
7948                        case 'NATS-DANO':
7949                        case 'ISO-IR-9-1':
7950                        case 'CSNATSDANO':
7951                                return 'NATS-DANO';
7952
7953                        case 'NATS-DANO-ADD':
7954                        case 'ISO-IR-9-2':
7955                        case 'CSNATSDANOADD':
7956                                return 'NATS-DANO-ADD';
7957
7958                        case 'SEN_850200_B':
7959                        case 'ISO-IR-10':
7960                        case 'FI':
7961                        case 'ISO646-FI':
7962                        case 'ISO646-SE':
7963                        case 'SE':
7964                        case 'CSISO10SWEDISH':
7965                                return 'SEN_850200_B';
7966
7967                        case 'KS_C_5601-1987':
7968                        case 'ISO-IR-149':
7969                        case 'KS_C_5601-1989':
7970                        case 'KSC_5601':
7971                        case 'KOREAN':
7972                        case 'CSKSC56011987':
7973                                return 'KS_C_5601-1987';
7974
7975                        case 'ISO-2022-KR':
7976                        case 'CSISO2022KR':
7977                                return 'ISO-2022-KR';
7978
7979                        case 'EUC-KR':
7980                        case 'CSEUCKR':
7981                                return 'EUC-KR';
7982
7983                        case 'ISO-2022-JP':
7984                        case 'CSISO2022JP':
7985                                return 'ISO-2022-JP';
7986
7987                        case 'ISO-2022-JP-2':
7988                        case 'CSISO2022JP2':
7989                                return 'ISO-2022-JP-2';
7990
7991                        case 'JIS_C6220-1969-JP':
7992                        case 'JIS_C6220-1969':
7993                        case 'ISO-IR-13':
7994                        case 'KATAKANA':
7995                        case 'X0201-7':
7996                        case 'CSISO13JISC6220JP':
7997                                return 'JIS_C6220-1969-jp';
7998
7999                        case 'JIS_C6220-1969-RO':
8000                        case 'ISO-IR-14':
8001                        case 'JP':
8002                        case 'ISO646-JP':
8003                        case 'CSISO14JISC6220RO':
8004                                return 'JIS_C6220-1969-ro';
8005
8006                        case 'PT':
8007                        case 'ISO-IR-16':
8008                        case 'ISO646-PT':
8009                        case 'CSISO16PORTUGUESE':
8010                                return 'PT';
8011
8012                        case 'GREEK7-OLD':
8013                        case 'ISO-IR-18':
8014                        case 'CSISO18GREEK7OLD':
8015                                return 'greek7-old';
8016
8017                        case 'LATIN-GREEK':
8018                        case 'ISO-IR-19':
8019                        case 'CSISO19LATINGREEK':
8020                                return 'latin-greek';
8021
8022                        case 'NF_Z_62-010_(1973)':
8023                        case 'ISO-IR-25':
8024                        case 'ISO646-FR1':
8025                        case 'CSISO25FRENCH':
8026                                return 'NF_Z_62-010_(1973)';
8027
8028                        case 'LATIN-GREEK-1':
8029                        case 'ISO-IR-27':
8030                        case 'CSISO27LATINGREEK1':
8031                                return 'Latin-greek-1';
8032
8033                        case 'ISO_5427':
8034                        case 'ISO-IR-37':
8035                        case 'CSISO5427CYRILLIC':
8036                                return 'ISO_5427';
8037
8038                        case 'JIS_C6226-1978':
8039                        case 'ISO-IR-42':
8040                        case 'CSISO42JISC62261978':
8041                                return 'JIS_C6226-1978';
8042
8043                        case 'BS_VIEWDATA':
8044                        case 'ISO-IR-47':
8045                        case 'CSISO47BSVIEWDATA':
8046                                return 'BS_viewdata';
8047
8048                        case 'INIS':
8049                        case 'ISO-IR-49':
8050                        case 'CSISO49INIS':
8051                                return 'INIS';
8052
8053                        case 'INIS-8':
8054                        case 'ISO-IR-50':
8055                        case 'CSISO50INIS8':
8056                                return 'INIS-8';
8057
8058                        case 'INIS-CYRILLIC':
8059                        case 'ISO-IR-51':
8060                        case 'CSISO51INISCYRILLIC':
8061                                return 'INIS-cyrillic';
8062
8063                        case 'ISO_5427:1981':
8064                        case 'ISO-IR-54':
8065                        case 'ISO5427CYRILLIC1981':
8066                                return 'ISO_5427:1981';
8067
8068                        case 'ISO_5428:1980':
8069                        case 'ISO-IR-55':
8070                        case 'CSISO5428GREEK':
8071                                return 'ISO_5428:1980';
8072
8073                        case 'GB_1988-80':
8074                        case 'ISO-IR-57':
8075                        case 'CN':
8076                        case 'ISO646-CN':
8077                        case 'CSISO57GB1988':
8078                                return 'GB_1988-80';
8079
8080                        case 'GB_2312-80':
8081                        case 'ISO-IR-58':
8082                        case 'CHINESE':
8083                        case 'CSISO58GB231280':
8084                                return 'GB_2312-80';
8085
8086                        case 'NS_4551-2':
8087                        case 'ISO646-NO2':
8088                        case 'ISO-IR-61':
8089                        case 'NO2':
8090                        case 'CSISO61NORWEGIAN2':
8091                                return 'NS_4551-2';
8092
8093                        case 'VIDEOTEX-SUPPL':
8094                        case 'ISO-IR-70':
8095                        case 'CSISO70VIDEOTEXSUPP1':
8096                                return 'videotex-suppl';
8097
8098                        case 'PT2':
8099                        case 'ISO-IR-84':
8100                        case 'ISO646-PT2':
8101                        case 'CSISO84PORTUGUESE2':
8102                                return 'PT2';
8103
8104                        case 'ES2':
8105                        case 'ISO-IR-85':
8106                        case 'ISO646-ES2':
8107                        case 'CSISO85SPANISH2':
8108                                return 'ES2';
8109
8110                        case 'MSZ_7795.3':
8111                        case 'ISO-IR-86':
8112                        case 'ISO646-HU':
8113                        case 'HU':
8114                        case 'CSISO86HUNGARIAN':
8115                                return 'MSZ_7795.3';
8116
8117                        case 'JIS_C6226-1983':
8118                        case 'ISO-IR-87':
8119                        case 'X0208':
8120                        case 'JIS_X0208-1983':
8121                        case 'CSISO87JISX0208':
8122                                return 'JIS_C6226-1983';
8123
8124                        case 'GREEK7':
8125                        case 'ISO-IR-88':
8126                        case 'CSISO88GREEK7':
8127                                return 'greek7';
8128
8129                        case 'ASMO_449':
8130                        case 'ISO_9036':
8131                        case 'ARABIC7':
8132                        case 'ISO-IR-89':
8133                        case 'CSISO89ASMO449':
8134                                return 'ASMO_449';
8135
8136                        case 'ISO-IR-90':
8137                        case 'CSISO90':
8138                                return 'iso-ir-90';
8139
8140                        case 'JIS_C6229-1984-A':
8141                        case 'ISO-IR-91':
8142                        case 'JP-OCR-A':
8143                        case 'CSISO91JISC62291984A':
8144                                return 'JIS_C6229-1984-a';
8145
8146                        case 'JIS_C6229-1984-B':
8147                        case 'ISO-IR-92':
8148                        case 'ISO646-JP-OCR-B':
8149                        case 'JP-OCR-B':
8150                        case 'CSISO92JISC62991984B':
8151                                return 'JIS_C6229-1984-b';
8152
8153                        case 'JIS_C6229-1984-B-ADD':
8154                        case 'ISO-IR-93':
8155                        case 'JP-OCR-B-ADD':
8156                        case 'CSISO93JIS62291984BADD':
8157                                return 'JIS_C6229-1984-b-add';
8158
8159                        case 'JIS_C6229-1984-HAND':
8160                        case 'ISO-IR-94':
8161                        case 'JP-OCR-HAND':
8162                        case 'CSISO94JIS62291984HAND':
8163                                return 'JIS_C6229-1984-hand';
8164
8165                        case 'JIS_C6229-1984-HAND-ADD':
8166                        case 'ISO-IR-95':
8167                        case 'JP-OCR-HAND-ADD':
8168                        case 'CSISO95JIS62291984HANDADD':
8169                                return 'JIS_C6229-1984-hand-add';
8170
8171                        case 'JIS_C6229-1984-KANA':
8172                        case 'ISO-IR-96':
8173                        case 'CSISO96JISC62291984KANA':
8174                                return 'JIS_C6229-1984-kana';
8175
8176                        case 'ISO_2033-1983':
8177                        case 'ISO-IR-98':
8178                        case 'E13B':
8179                        case 'CSISO2033':
8180                                return 'ISO_2033-1983';
8181
8182                        case 'ANSI_X3.110-1983':
8183                        case 'ISO-IR-99':
8184                        case 'CSA_T500-1983':
8185                        case 'NAPLPS':
8186                        case 'CSISO99NAPLPS':
8187                                return 'ANSI_X3.110-1983';
8188
8189                        case 'T.61-7BIT':
8190                        case 'ISO-IR-102':
8191                        case 'CSISO102T617BIT':
8192                                return 'T.61-7bit';
8193
8194                        case 'T.61-8BIT':
8195                        case 'T.61':
8196                        case 'ISO-IR-103':
8197                        case 'CSISO103T618BIT':
8198                                return 'T.61-8bit';
8199
8200                        case 'ECMA-CYRILLIC':
8201                        case 'ISO-IR-111':
8202                        case 'KOI8-E':
8203                        case 'CSISO111ECMACYRILLIC':
8204                                return 'ECMA-cyrillic';
8205
8206                        case 'CSA_Z243.4-1985-1':
8207                        case 'ISO-IR-121':
8208                        case 'ISO646-CA':
8209                        case 'CSA7-1':
8210                        case 'CA':
8211                        case 'CSISO121CANADIAN1':
8212                                return 'CSA_Z243.4-1985-1';
8213
8214                        case 'CSA_Z243.4-1985-2':
8215                        case 'ISO-IR-122':
8216                        case 'ISO646-CA2':
8217                        case 'CSA7-2':
8218                        case 'CSISO122CANADIAN2':
8219                                return 'CSA_Z243.4-1985-2';
8220
8221                        case 'CSA_Z243.4-1985-GR':
8222                        case 'ISO-IR-123':
8223                        case 'CSISO123CSAZ24341985GR':
8224                                return 'CSA_Z243.4-1985-gr';
8225
8226                        case 'ISO_8859-6-E':
8227                        case 'CSISO88596E':
8228                        case 'ISO-8859-6-E':
8229                                return 'ISO-8859-6-E';
8230
8231                        case 'ISO_8859-6-I':
8232                        case 'CSISO88596I':
8233                        case 'ISO-8859-6-I':
8234                                return 'ISO-8859-6-I';
8235
8236                        case 'T.101-G2':
8237                        case 'ISO-IR-128':
8238                        case 'CSISO128T101G2':
8239                                return 'T.101-G2';
8240
8241                        case 'ISO_8859-8-E':
8242                        case 'CSISO88598E':
8243                        case 'ISO-8859-8-E':
8244                                return 'ISO-8859-8-E';
8245
8246                        case 'ISO_8859-8-I':
8247                        case 'CSISO88598I':
8248                        case 'ISO-8859-8-I':
8249                                return 'ISO-8859-8-I';
8250
8251                        case 'CSN_369103':
8252                        case 'ISO-IR-139':
8253                        case 'CSISO139CSN369103':
8254                                return 'CSN_369103';
8255
8256                        case 'JUS_I.B1.002':
8257                        case 'ISO-IR-141':
8258                        case 'ISO646-YU':
8259                        case 'JS':
8260                        case 'YU':
8261                        case 'CSISO141JUSIB1002':
8262                                return 'JUS_I.B1.002';
8263
8264                        case 'IEC_P27-1':
8265                        case 'ISO-IR-143':
8266                        case 'CSISO143IECP271':
8267                                return 'IEC_P27-1';
8268
8269                        case 'JUS_I.B1.003-SERB':
8270                        case 'ISO-IR-146':
8271                        case 'SERBIAN':
8272                        case 'CSISO146SERBIAN':
8273                                return 'JUS_I.B1.003-serb';
8274
8275                        case 'JUS_I.B1.003-MAC':
8276                        case 'MACEDONIAN':
8277                        case 'ISO-IR-147':
8278                        case 'CSISO147MACEDONIAN':
8279                                return 'JUS_I.B1.003-mac';
8280
8281                        case 'GREEK-CCITT':
8282                        case 'ISO-IR-150':
8283                        case 'CSISO150':
8284                        case 'CSISO150GREEKCCITT':
8285                                return 'greek-ccitt';
8286
8287                        case 'NC_NC00-10:81':
8288                        case 'CUBA':
8289                        case 'ISO-IR-151':
8290                        case 'ISO646-CU':
8291                        case 'CSISO151CUBA':
8292                                return 'NC_NC00-10:81';
8293
8294                        case 'ISO_6937-2-25':
8295                        case 'ISO-IR-152':
8296                        case 'CSISO6937ADD':
8297                                return 'ISO_6937-2-25';
8298
8299                        case 'GOST_19768-74':
8300                        case 'ST_SEV_358-88':
8301                        case 'ISO-IR-153':
8302                        case 'CSISO153GOST1976874':
8303                                return 'GOST_19768-74';
8304
8305                        case 'ISO_8859-SUPP':
8306                        case 'ISO-IR-154':
8307                        case 'LATIN1-2-5':
8308                        case 'CSISO8859SUPP':
8309                                return 'ISO_8859-supp';
8310
8311                        case 'ISO_10367-BOX':
8312                        case 'ISO-IR-155':
8313                        case 'CSISO10367BOX':
8314                                return 'ISO_10367-box';
8315
8316                        case 'LATIN-LAP':
8317                        case 'LAP':
8318                        case 'ISO-IR-158':
8319                        case 'CSISO158LAP':
8320                                return 'latin-lap';
8321
8322                        case 'JIS_X0212-1990':
8323                        case 'X0212':
8324                        case 'ISO-IR-159':
8325                        case 'CSISO159JISX02121990':
8326                                return 'JIS_X0212-1990';
8327
8328                        case 'DS_2089':
8329                        case 'DS2089':
8330                        case 'ISO646-DK':
8331                        case 'DK':
8332                        case 'CSISO646DANISH':
8333                                return 'DS_2089';
8334
8335                        case 'US-DK':
8336                        case 'CSUSDK':
8337                                return 'us-dk';
8338
8339                        case 'DK-US':
8340                        case 'CSDKUS':
8341                                return 'dk-us';
8342
8343                        case 'KSC5636':
8344                        case 'ISO646-KR':
8345                        case 'CSKSC5636':
8346                                return 'KSC5636';
8347
8348                        case 'UNICODE-1-1-UTF-7':
8349                        case 'CSUNICODE11UTF7':
8350                                return 'UNICODE-1-1-UTF-7';
8351
8352                        case 'ISO-2022-CN':
8353                                return 'ISO-2022-CN';
8354
8355                        case 'ISO-2022-CN-EXT':
8356                                return 'ISO-2022-CN-EXT';
8357
8358                        case 'UTF-8':
8359                                return 'UTF-8';
8360
8361                        case 'ISO-8859-13':
8362                                return 'ISO-8859-13';
8363
8364                        case 'ISO-8859-14':
8365                        case 'ISO-IR-199':
8366                        case 'ISO_8859-14:1998':
8367                        case 'ISO_8859-14':
8368                        case 'LATIN8':
8369                        case 'ISO-CELTIC':
8370                        case 'L8':
8371                                return 'ISO-8859-14';
8372
8373                        case 'ISO-8859-15':
8374                        case 'ISO_8859-15':
8375                        case 'LATIN-9':
8376                                return 'ISO-8859-15';
8377
8378                        case 'ISO-8859-16':
8379                        case 'ISO-IR-226':
8380                        case 'ISO_8859-16:2001':
8381                        case 'ISO_8859-16':
8382                        case 'LATIN10':
8383                        case 'L10':
8384                                return 'ISO-8859-16';
8385
8386                        case 'GBK':
8387                        case 'CP936':
8388                        case 'MS936':
8389                        case 'WINDOWS-936':
8390                                return 'GBK';
8391
8392                        case 'GB18030':
8393                                return 'GB18030';
8394
8395                        case 'OSD_EBCDIC_DF04_15':
8396                                return 'OSD_EBCDIC_DF04_15';
8397
8398                        case 'OSD_EBCDIC_DF03_IRV':
8399                                return 'OSD_EBCDIC_DF03_IRV';
8400
8401                        case 'OSD_EBCDIC_DF04_1':
8402                                return 'OSD_EBCDIC_DF04_1';
8403
8404                        case 'ISO-11548-1':
8405                        case 'ISO_11548-1':
8406                        case 'ISO_TR_11548-1':
8407                        case 'CSISO115481':
8408                                return 'ISO-11548-1';
8409
8410                        case 'KZ-1048':
8411                        case 'STRK1048-2002':
8412                        case 'RK1048':
8413                        case 'CSKZ1048':
8414                                return 'KZ-1048';
8415
8416                        case 'ISO-10646-UCS-2':
8417                        case 'CSUNICODE':
8418                                return 'ISO-10646-UCS-2';
8419
8420                        case 'ISO-10646-UCS-4':
8421                        case 'CSUCS4':
8422                                return 'ISO-10646-UCS-4';
8423
8424                        case 'ISO-10646-UCS-BASIC':
8425                        case 'CSUNICODEASCII':
8426                                return 'ISO-10646-UCS-Basic';
8427
8428                        case 'ISO-10646-UNICODE-LATIN1':
8429                        case 'CSUNICODELATIN1':
8430                        case 'ISO-10646':
8431                                return 'ISO-10646-Unicode-Latin1';
8432
8433                        case 'ISO-10646-J-1':
8434                                return 'ISO-10646-J-1';
8435
8436                        case 'ISO-UNICODE-IBM-1261':
8437                        case 'CSUNICODEIBM1261':
8438                                return 'ISO-Unicode-IBM-1261';
8439
8440                        case 'ISO-UNICODE-IBM-1268':
8441                        case 'CSUNICODEIBM1268':
8442                                return 'ISO-Unicode-IBM-1268';
8443
8444                        case 'ISO-UNICODE-IBM-1276':
8445                        case 'CSUNICODEIBM1276':
8446                                return 'ISO-Unicode-IBM-1276';
8447
8448                        case 'ISO-UNICODE-IBM-1264':
8449                        case 'CSUNICODEIBM1264':
8450                                return 'ISO-Unicode-IBM-1264';
8451
8452                        case 'ISO-UNICODE-IBM-1265':
8453                        case 'CSUNICODEIBM1265':
8454                                return 'ISO-Unicode-IBM-1265';
8455
8456                        case 'UNICODE-1-1':
8457                        case 'CSUNICODE11':
8458                                return 'UNICODE-1-1';
8459
8460                        case 'SCSU':
8461                                return 'SCSU';
8462
8463                        case 'UTF-7':
8464                                return 'UTF-7';
8465
8466                        case 'UTF-16BE':
8467                                return 'UTF-16BE';
8468
8469                        case 'UTF-16LE':
8470                                return 'UTF-16LE';
8471
8472                        case 'UTF-16':
8473                                return 'UTF-16';
8474
8475                        case 'CESU-8':
8476                        case 'CSCESU-8':
8477                                return 'CESU-8';
8478
8479                        case 'UTF-32':
8480                                return 'UTF-32';
8481
8482                        case 'UTF-32BE':
8483                                return 'UTF-32BE';
8484
8485                        case 'UTF-32LE':
8486                                return 'UTF-32LE';
8487
8488                        case 'BOCU-1':
8489                        case 'CSBOCU-1':
8490                                return 'BOCU-1';
8491
8492                        case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
8493                        case 'CSWINDOWS30LATIN1':
8494                                return 'ISO-8859-1-Windows-3.0-Latin-1';
8495
8496                        case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
8497                        case 'CSWINDOWS31LATIN1':
8498                                return 'ISO-8859-1-Windows-3.1-Latin-1';
8499
8500                        case 'ISO-8859-2-WINDOWS-LATIN-2':
8501                        case 'CSWINDOWS31LATIN2':
8502                                return 'ISO-8859-2-Windows-Latin-2';
8503
8504                        case 'ISO-8859-9-WINDOWS-LATIN-5':
8505                        case 'CSWINDOWS31LATIN5':
8506                                return 'ISO-8859-9-Windows-Latin-5';
8507
8508                        case 'HP-ROMAN8':
8509                        case 'ROMAN8':
8510                        case 'R8':
8511                        case 'CSHPROMAN8':
8512                                return 'hp-roman8';
8513
8514                        case 'ADOBE-STANDARD-ENCODING':
8515                        case 'CSADOBESTANDARDENCODING':
8516                                return 'Adobe-Standard-Encoding';
8517
8518                        case 'VENTURA-US':
8519                        case 'CSVENTURAUS':
8520                                return 'Ventura-US';
8521
8522                        case 'VENTURA-INTERNATIONAL':
8523                        case 'CSVENTURAINTERNATIONAL':
8524                                return 'Ventura-International';
8525
8526                        case 'DEC-MCS':
8527                        case 'DEC':
8528                        case 'CSDECMCS':
8529                                return 'DEC-MCS';
8530
8531                        case 'IBM850':
8532                        case 'CP850':
8533                        case '850':
8534                        case 'CSPC850MULTILINGUAL':
8535                                return 'IBM850';
8536
8537                        case 'PC8-DANISH-NORWEGIAN':
8538                        case 'CSPC8DANISHNORWEGIAN':
8539                                return 'PC8-Danish-Norwegian';
8540
8541                        case 'IBM862':
8542                        case 'CP862':
8543                        case '862':
8544                        case 'CSPC862LATINHEBREW':
8545                                return 'IBM862';
8546
8547                        case 'PC8-TURKISH':
8548                        case 'CSPC8TURKISH':
8549                                return 'PC8-Turkish';
8550
8551                        case 'IBM-SYMBOLS':
8552                        case 'CSIBMSYMBOLS':
8553                                return 'IBM-Symbols';
8554
8555                        case 'IBM-THAI':
8556                        case 'CSIBMTHAI':
8557