Assignment MDL-22843
[moodle.git] / lib / simplepie / simplepie.inc
1 <?php
2 /**
3  * SimplePie
4  *
5  * A PHP-Based RSS and Atom Feed Framework.
6  * Takes the hard work out of managing a complete RSS/Atom solution.
7  *
8  * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification, are
12  * permitted provided that the following conditions are met:
13  *
14  *      * Redistributions of source code must retain the above copyright notice, this list of
15  *        conditions and the following disclaimer.
16  *
17  *      * Redistributions in binary form must reproduce the above copyright notice, this list
18  *        of conditions and the following disclaimer in the documentation and/or other materials
19  *        provided with the distribution.
20  *
21  *      * Neither the name of the SimplePie Team nor the names of its contributors may be used
22  *        to endorse or promote products derived from this software without specific prior
23  *        written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * @package SimplePie
36  * @version 1.2
37  * @copyright 2004-2009 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  */
46 /**
47  * SimplePie Name
48  */
49 define('SIMPLEPIE_NAME', 'SimplePie');
51 /**
52  * SimplePie Version
53  */
54 define('SIMPLEPIE_VERSION', '1.2');
56 /**
57  * SimplePie Build
58  */
59 define('SIMPLEPIE_BUILD', '20090627192103');
61 /**
62  * SimplePie Website URL
63  */
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
66 /**
67  * SimplePie Useragent
68  * @see SimplePie::set_useragent()
69  */
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
72 /**
73  * SimplePie Linkback
74  */
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
77 /**
78  * No Autodiscovery
79  * @see SimplePie::set_autodiscovery_level()
80  */
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
83 /**
84  * Feed Link Element Autodiscovery
85  * @see SimplePie::set_autodiscovery_level()
86  */
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
89 /**
90  * Local Feed Extension Autodiscovery
91  * @see SimplePie::set_autodiscovery_level()
92  */
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
95 /**
96  * Local Feed Body Autodiscovery
97  * @see SimplePie::set_autodiscovery_level()
98  */
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
101 /**
102  * Remote Feed Extension Autodiscovery
103  * @see SimplePie::set_autodiscovery_level()
104  */
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
107 /**
108  * Remote Feed Body Autodiscovery
109  * @see SimplePie::set_autodiscovery_level()
110  */
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
113 /**
114  * All Feed Autodiscovery
115  * @see SimplePie::set_autodiscovery_level()
116  */
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
119 /**
120  * No known feed type
121  */
122 define('SIMPLEPIE_TYPE_NONE', 0);
124 /**
125  * RSS 0.90
126  */
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
129 /**
130  * RSS 0.91 (Netscape)
131  */
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
134 /**
135  * RSS 0.91 (Userland)
136  */
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
139 /**
140  * RSS 0.91 (both Netscape and Userland)
141  */
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
144 /**
145  * RSS 0.92
146  */
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
149 /**
150  * RSS 0.93
151  */
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
154 /**
155  * RSS 0.94
156  */
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
159 /**
160  * RSS 1.0
161  */
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
164 /**
165  * RSS 2.0
166  */
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
169 /**
170  * RDF-based RSS
171  */
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
174 /**
175  * Non-RDF-based RSS (truly intended as syndication format)
176  */
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
179 /**
180  * All RSS
181  */
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
184 /**
185  * Atom 0.3
186  */
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
189 /**
190  * Atom 1.0
191  */
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
194 /**
195  * All Atom
196  */
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
199 /**
200  * All feed types
201  */
202 define('SIMPLEPIE_TYPE_ALL', 1023);
204 /**
205  * No construct
206  */
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
209 /**
210  * Text construct
211  */
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
214 /**
215  * HTML construct
216  */
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
219 /**
220  * XHTML construct
221  */
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
224 /**
225  * base64-encoded construct
226  */
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
229 /**
230  * IRI construct
231  */
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
234 /**
235  * A construct that might be HTML
236  */
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
239 /**
240  * All constructs
241  */
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
244 /**
245  * Don't change case
246  */
247 define('SIMPLEPIE_SAME_CASE', 1);
249 /**
250  * Change to lowercase
251  */
252 define('SIMPLEPIE_LOWERCASE', 2);
254 /**
255  * Change to uppercase
256  */
257 define('SIMPLEPIE_UPPERCASE', 4);
259 /**
260  * PCRE for HTML attributes
261  */
262 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
264 /**
265  * PCRE for XML attributes
266  */
267 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
269 /**
270  * XML Namespace
271  */
272 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
274 /**
275  * Atom 1.0 Namespace
276  */
277 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
279 /**
280  * Atom 0.3 Namespace
281  */
282 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
284 /**
285  * RDF Namespace
286  */
287 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
289 /**
290  * RSS 0.90 Namespace
291  */
292 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
294 /**
295  * RSS 1.0 Namespace
296  */
297 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
299 /**
300  * RSS 1.0 Content Module Namespace
301  */
302 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
304 /**
305  * RSS 2.0 Namespace
306  * (Stupid, I know, but I'm certain it will confuse people less with support.)
307  */
308 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
310 /**
311  * DC 1.0 Namespace
312  */
313 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
315 /**
316  * DC 1.1 Namespace
317  */
318 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
320 /**
321  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
322  */
323 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
325 /**
326  * GeoRSS Namespace
327  */
328 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
330 /**
331  * Media RSS Namespace
332  */
333 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
335 /**
336  * Wrong Media RSS Namespace
337  */
338 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
340 /**
341  * iTunes RSS Namespace
342  */
343 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
345 /**
346  * XHTML Namespace
347  */
348 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
350 /**
351  * IANA Link Relations Registry
352  */
353 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
355 /**
356  * Whether we're running on PHP5
357  */
358 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
360 /**
361  * No file source
362  */
363 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
365 /**
366  * Remote file source
367  */
368 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
370 /**
371  * Local file source
372  */
373 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
375 /**
376  * fsockopen() file source
377  */
378 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
380 /**
381  * cURL file source
382  */
383 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
385 /**
386  * file_get_contents() file source
387  */
388 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
390 /**
391  * SimplePie
392  *
393  * @package SimplePie
394  */
395 class SimplePie
397         /**
398          * @var array Raw data
399          * @access private
400          */
401         var $data = array();
403         /**
404          * @var mixed Error string
405          * @access private
406          */
407         var $error;
409         /**
410          * @var object Instance of SimplePie_Sanitize (or other class)
411          * @see SimplePie::set_sanitize_class()
412          * @access private
413          */
414         var $sanitize;
416         /**
417          * @var string SimplePie Useragent
418          * @see SimplePie::set_useragent()
419          * @access private
420          */
421         var $useragent = SIMPLEPIE_USERAGENT;
423         /**
424          * @var string Feed URL
425          * @see SimplePie::set_feed_url()
426          * @access private
427          */
428         var $feed_url;
430         /**
431          * @var object Instance of SimplePie_File to use as a feed
432          * @see SimplePie::set_file()
433          * @access private
434          */
435         var $file;
437         /**
438          * @var string Raw feed data
439          * @see SimplePie::set_raw_data()
440          * @access private
441          */
442         var $raw_data;
444         /**
445          * @var int Timeout for fetching remote files
446          * @see SimplePie::set_timeout()
447          * @access private
448          */
449         var $timeout = 10;
451         /**
452          * @var bool Forces fsockopen() to be used for remote files instead
453          * of cURL, even if a new enough version is installed
454          * @see SimplePie::force_fsockopen()
455          * @access private
456          */
457         var $force_fsockopen = false;
459         /**
460          * @var bool Force the given data/URL to be treated as a feed no matter what
461          * it appears like
462          * @see SimplePie::force_feed()
463          * @access private
464          */
465         var $force_feed = false;
467         /**
468          * @var bool Enable/Disable XML dump
469          * @see SimplePie::enable_xml_dump()
470          * @access private
471          */
472         var $xml_dump = false;
474         /**
475          * @var bool Enable/Disable Caching
476          * @see SimplePie::enable_cache()
477          * @access private
478          */
479         var $cache = true;
481         /**
482          * @var int Cache duration (in seconds)
483          * @see SimplePie::set_cache_duration()
484          * @access private
485          */
486         var $cache_duration = 3600;
488         /**
489          * @var int Auto-discovery cache duration (in seconds)
490          * @see SimplePie::set_autodiscovery_cache_duration()
491          * @access private
492          */
493         var $autodiscovery_cache_duration = 604800; // 7 Days.
495         /**
496          * @var string Cache location (relative to executing script)
497          * @see SimplePie::set_cache_location()
498          * @access private
499          */
500         var $cache_location = './cache';
502         /**
503          * @var string Function that creates the cache filename
504          * @see SimplePie::set_cache_name_function()
505          * @access private
506          */
507         var $cache_name_function = 'md5';
509         /**
510          * @var bool Reorder feed by date descending
511          * @see SimplePie::enable_order_by_date()
512          * @access private
513          */
514         var $order_by_date = true;
516         /**
517          * @var mixed Force input encoding to be set to the follow value
518          * (false, or anything type-cast to false, disables this feature)
519          * @see SimplePie::set_input_encoding()
520          * @access private
521          */
522         var $input_encoding = false;
524         /**
525          * @var int Feed Autodiscovery Level
526          * @see SimplePie::set_autodiscovery_level()
527          * @access private
528          */
529         var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
531         /**
532          * @var string Class used for caching feeds
533          * @see SimplePie::set_cache_class()
534          * @access private
535          */
536         var $cache_class = 'SimplePie_Cache';
538         /**
539          * @var string Class used for locating feeds
540          * @see SimplePie::set_locator_class()
541          * @access private
542          */
543         var $locator_class = 'SimplePie_Locator';
545         /**
546          * @var string Class used for parsing feeds
547          * @see SimplePie::set_parser_class()
548          * @access private
549          */
550         var $parser_class = 'SimplePie_Parser';
552         /**
553          * @var string Class used for fetching feeds
554          * @see SimplePie::set_file_class()
555          * @access private
556          */
557         var $file_class = 'SimplePie_File';
559         /**
560          * @var string Class used for items
561          * @see SimplePie::set_item_class()
562          * @access private
563          */
564         var $item_class = 'SimplePie_Item';
566         /**
567          * @var string Class used for authors
568          * @see SimplePie::set_author_class()
569          * @access private
570          */
571         var $author_class = 'SimplePie_Author';
573         /**
574          * @var string Class used for categories
575          * @see SimplePie::set_category_class()
576          * @access private
577          */
578         var $category_class = 'SimplePie_Category';
580         /**
581          * @var string Class used for enclosures
582          * @see SimplePie::set_enclosures_class()
583          * @access private
584          */
585         var $enclosure_class = 'SimplePie_Enclosure';
587         /**
588          * @var string Class used for Media RSS <media:text> captions
589          * @see SimplePie::set_caption_class()
590          * @access private
591          */
592         var $caption_class = 'SimplePie_Caption';
594         /**
595          * @var string Class used for Media RSS <media:copyright>
596          * @see SimplePie::set_copyright_class()
597          * @access private
598          */
599         var $copyright_class = 'SimplePie_Copyright';
601         /**
602          * @var string Class used for Media RSS <media:credit>
603          * @see SimplePie::set_credit_class()
604          * @access private
605          */
606         var $credit_class = 'SimplePie_Credit';
608         /**
609          * @var string Class used for Media RSS <media:rating>
610          * @see SimplePie::set_rating_class()
611          * @access private
612          */
613         var $rating_class = 'SimplePie_Rating';
615         /**
616          * @var string Class used for Media RSS <media:restriction>
617          * @see SimplePie::set_restriction_class()
618          * @access private
619          */
620         var $restriction_class = 'SimplePie_Restriction';
622         /**
623          * @var string Class used for content-type sniffing
624          * @see SimplePie::set_content_type_sniffer_class()
625          * @access private
626          */
627         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
629         /**
630          * @var string Class used for item sources.
631          * @see SimplePie::set_source_class()
632          * @access private
633          */
634         var $source_class = 'SimplePie_Source';
636         /**
637          * @var mixed Set javascript query string parameter (false, or
638          * anything type-cast to false, disables this feature)
639          * @see SimplePie::set_javascript()
640          * @access private
641          */
642         var $javascript = 'js';
644         /**
645          * @var int Maximum number of feeds to check with autodiscovery
646          * @see SimplePie::set_max_checked_feeds()
647          * @access private
648          */
649         var $max_checked_feeds = 10;
651         /**
652          * @var array All the feeds found during the autodiscovery process
653          * @see SimplePie::get_all_discovered_feeds()
654          * @access private
655          */
656         var $all_discovered_feeds = array();
658         /**
659          * @var string Web-accessible path to the handler_favicon.php file.
660          * @see SimplePie::set_favicon_handler()
661          * @access private
662          */
663         var $favicon_handler = '';
665         /**
666          * @var string Web-accessible path to the handler_image.php file.
667          * @see SimplePie::set_image_handler()
668          * @access private
669          */
670         var $image_handler = '';
672         /**
673          * @var array Stores the URLs when multiple feeds are being initialized.
674          * @see SimplePie::set_feed_url()
675          * @access private
676          */
677         var $multifeed_url = array();
679         /**
680          * @var array Stores SimplePie objects when multiple feeds initialized.
681          * @access private
682          */
683         var $multifeed_objects = array();
685         /**
686          * @var array Stores the get_object_vars() array for use with multifeeds.
687          * @see SimplePie::set_feed_url()
688          * @access private
689          */
690         var $config_settings = null;
692         /**
693          * @var integer Stores the number of items to return per-feed with multifeeds.
694          * @see SimplePie::set_item_limit()
695          * @access private
696          */
697         var $item_limit = 0;
699         /**
700          * @var array Stores the default attributes to be stripped by strip_attributes().
701          * @see SimplePie::strip_attributes()
702          * @access private
703          */
704         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
706         /**
707          * @var array Stores the default tags to be stripped by strip_htmltags().
708          * @see SimplePie::strip_htmltags()
709          * @access private
710          */
711         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
713         /**
714          * The SimplePie class contains feed level data and options
715          *
716          * There are two ways that you can create a new SimplePie object. The first
717          * is by passing a feed URL as a parameter to the SimplePie constructor
718          * (as well as optionally setting the cache location and cache expiry). This
719          * will initialise the whole feed with all of the default settings, and you
720          * can begin accessing methods and properties immediately.
721          *
722          * The second way is to create the SimplePie object with no parameters
723          * at all. This will enable you to set configuration options. After setting
724          * them, you must initialise the feed using $feed->init(). At that point the
725          * object's methods and properties will be available to you. This format is
726          * what is used throughout this documentation.
727          *
728          * @access public
729          * @since 1.0 Preview Release
730          * @param string $feed_url This is the URL you want to parse.
731          * @param string $cache_location This is where you want the cache to be stored.
732          * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
733          */
734         function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
735         {
736                 // Other objects, instances created here so we can set options on them
737                 $this->sanitize =& new SimplePie_Sanitize;
739                 // Set options if they're passed to the constructor
740                 if ($cache_location !== null)
741                 {
742                         $this->set_cache_location($cache_location);
743                 }
745                 if ($cache_duration !== null)
746                 {
747                         $this->set_cache_duration($cache_duration);
748                 }
750                 // Only init the script if we're passed a feed URL
751                 if ($feed_url !== null)
752                 {
753                         $this->set_feed_url($feed_url);
754                         $this->init();
755                 }
756         }
758         /**
759          * Used for converting object to a string
760          */
761         function __toString()
762         {
763                 return md5(serialize($this->data));
764         }
766         /**
767          * Remove items that link back to this before destroying this object
768          */
769         function __destruct()
770         {
771                 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
772                 {
773                         if (!empty($this->data['items']))
774                         {
775                                 foreach ($this->data['items'] as $item)
776                                 {
777                                         $item->__destruct();
778                                 }
779                                 unset($item, $this->data['items']);
780                         }
781                         if (!empty($this->data['ordered_items']))
782                         {
783                                 foreach ($this->data['ordered_items'] as $item)
784                                 {
785                                         $item->__destruct();
786                                 }
787                                 unset($item, $this->data['ordered_items']);
788                         }
789                 }
790         }
792         /**
793          * Force the given data/URL to be treated as a feed no matter what it
794          * appears like
795          *
796          * @access public
797          * @since 1.1
798          * @param bool $enable Force the given data/URL to be treated as a feed
799          */
800         function force_feed($enable = false)
801         {
802                 $this->force_feed = (bool) $enable;
803         }
805         /**
806          * This is the URL of the feed you want to parse.
807          *
808          * This allows you to enter the URL of the feed you want to parse, or the
809          * website you want to try to use auto-discovery on. This takes priority
810          * over any set raw data.
811          *
812          * You can set multiple feeds to mash together by passing an array instead
813          * of a string for the $url. Remember that with each additional feed comes
814          * additional processing and resources.
815          *
816          * @access public
817          * @since 1.0 Preview Release
818          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
819          * @see SimplePie::set_raw_data()
820          */
821         function set_feed_url($url)
822         {
823                 if (is_array($url))
824                 {
825                         $this->multifeed_url = array();
826                         foreach ($url as $value)
827                         {
828                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
829                         }
830                 }
831                 else
832                 {
833                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
834                 }
835         }
837         /**
838          * Provides an instance of SimplePie_File to use as a feed
839          *
840          * @access public
841          * @param object &$file Instance of SimplePie_File (or subclass)
842          * @return bool True on success, false on failure
843          */
844         function set_file(&$file)
845         {
846                 if (is_a($file, 'SimplePie_File'))
847                 {
848                         $this->feed_url = $file->url;
849                         $this->file =& $file;
850                         return true;
851                 }
852                 return false;
853         }
855         /**
856          * Allows you to use a string of RSS/Atom data instead of a remote feed.
857          *
858          * If you have a feed available as a string in PHP, you can tell SimplePie
859          * to parse that data string instead of a remote feed. Any set feed URL
860          * takes precedence.
861          *
862          * @access public
863          * @since 1.0 Beta 3
864          * @param string $data RSS or Atom data as a string.
865          * @see SimplePie::set_feed_url()
866          */
867         function set_raw_data($data)
868         {
869                 $this->raw_data = $data;
870         }
872         /**
873          * Allows you to override the default timeout for fetching remote feeds.
874          *
875          * This allows you to change the maximum time the feed's server to respond
876          * and send the feed back.
877          *
878          * @access public
879          * @since 1.0 Beta 3
880          * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
881          */
882         function set_timeout($timeout = 10)
883         {
884                 $this->timeout = (int) $timeout;
885         }
887         /**
888          * Forces SimplePie to use fsockopen() instead of the preferred cURL
889          * functions.
890          *
891          * @access public
892          * @since 1.0 Beta 3
893          * @param bool $enable Force fsockopen() to be used
894          */
895         function force_fsockopen($enable = false)
896         {
897                 $this->force_fsockopen = (bool) $enable;
898         }
900         /**
901          * Outputs the raw XML content of the feed, after it has gone through
902          * SimplePie's filters.
903          *
904          * Used only for debugging, this function will output the XML content as
905          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
906          * before trying to parse it. Many parts of the feed are re-written in
907          * memory, and in the end, you have a parsable feed. XML dump shows you the
908          * actual XML that SimplePie tries to parse, which may or may not be very
909          * different from the original feed.
910          *
911          * @access public
912          * @since 1.0 Preview Release
913          * @param bool $enable Enable XML dump
914          */
915         function enable_xml_dump($enable = false)
916         {
917                 $this->xml_dump = (bool) $enable;
918         }
920         /**
921          * Enables/disables caching in SimplePie.
922          *
923          * This option allows you to disable caching all-together in SimplePie.
924          * However, disabling the cache can lead to longer load times.
925          *
926          * @access public
927          * @since 1.0 Preview Release
928          * @param bool $enable Enable caching
929          */
930         function enable_cache($enable = true)
931         {
932                 $this->cache = (bool) $enable;
933         }
935         /**
936          * Set the length of time (in seconds) that the contents of a feed
937          * will be cached.
938          *
939          * @access public
940          * @param int $seconds The feed content cache duration.
941          */
942         function set_cache_duration($seconds = 3600)
943         {
944                 $this->cache_duration = (int) $seconds;
945         }
947         /**
948          * Set the length of time (in seconds) that the autodiscovered feed
949          * URL will be cached.
950          *
951          * @access public
952          * @param int $seconds The autodiscovered feed URL cache duration.
953          */
954         function set_autodiscovery_cache_duration($seconds = 604800)
955         {
956                 $this->autodiscovery_cache_duration = (int) $seconds;
957         }
959         /**
960          * Set the file system location where the cached files should be stored.
961          *
962          * @access public
963          * @param string $location The file system location.
964          */
965         function set_cache_location($location = './cache')
966         {
967                 $this->cache_location = (string) $location;
968         }
970         /**
971          * Determines whether feed items should be sorted into reverse chronological order.
972          *
973          * @access public
974          * @param bool $enable Sort as reverse chronological order.
975          */
976         function enable_order_by_date($enable = true)
977         {
978                 $this->order_by_date = (bool) $enable;
979         }
981         /**
982          * Allows you to override the character encoding reported by the feed.
983          *
984          * @access public
985          * @param string $encoding Character encoding.
986          */
987         function set_input_encoding($encoding = false)
988         {
989                 if ($encoding)
990                 {
991                         $this->input_encoding = (string) $encoding;
992                 }
993                 else
994                 {
995                         $this->input_encoding = false;
996                 }
997         }
999         /**
1000          * Set how much feed autodiscovery to do
1001          *
1002          * @access public
1003          * @see SIMPLEPIE_LOCATOR_NONE
1004          * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1005          * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1006          * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1007          * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1008          * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1009          * @see SIMPLEPIE_LOCATOR_ALL
1010          * @param int $level Feed Autodiscovery Level (level can be a
1011          * combination of the above constants, see bitwise OR operator)
1012          */
1013         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1014         {
1015                 $this->autodiscovery = (int) $level;
1016         }
1018         /**
1019          * Allows you to change which class SimplePie uses for caching.
1020          * Useful when you are overloading or extending SimplePie's default classes.
1021          *
1022          * @access public
1023          * @param string $class Name of custom class.
1024          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1025          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1026          */
1027         function set_cache_class($class = 'SimplePie_Cache')
1028         {
1029                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1030                 {
1031                         $this->cache_class = $class;
1032                         return true;
1033                 }
1034                 return false;
1035         }
1037         /**
1038          * Allows you to change which class SimplePie uses for auto-discovery.
1039          * Useful when you are overloading or extending SimplePie's default classes.
1040          *
1041          * @access public
1042          * @param string $class Name of custom class.
1043          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1044          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1045          */
1046         function set_locator_class($class = 'SimplePie_Locator')
1047         {
1048                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1049                 {
1050                         $this->locator_class = $class;
1051                         return true;
1052                 }
1053                 return false;
1054         }
1056         /**
1057          * Allows you to change which class SimplePie uses for XML parsing.
1058          * Useful when you are overloading or extending SimplePie's default classes.
1059          *
1060          * @access public
1061          * @param string $class Name of custom class.
1062          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1063          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1064          */
1065         function set_parser_class($class = 'SimplePie_Parser')
1066         {
1067                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1068                 {
1069                         $this->parser_class = $class;
1070                         return true;
1071                 }
1072                 return false;
1073         }
1075         /**
1076          * Allows you to change which class SimplePie uses for remote file fetching.
1077          * Useful when you are overloading or extending SimplePie's default classes.
1078          *
1079          * @access public
1080          * @param string $class Name of custom class.
1081          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1082          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1083          */
1084         function set_file_class($class = 'SimplePie_File')
1085         {
1086                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1087                 {
1088                         $this->file_class = $class;
1089                         return true;
1090                 }
1091                 return false;
1092         }
1094         /**
1095          * Allows you to change which class SimplePie uses for data sanitization.
1096          * Useful when you are overloading or extending SimplePie's default classes.
1097          *
1098          * @access public
1099          * @param string $class Name of custom class.
1100          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1101          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1102          */
1103         function set_sanitize_class($class = 'SimplePie_Sanitize')
1104         {
1105                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1106                 {
1107                         $this->sanitize =& new $class;
1108                         return true;
1109                 }
1110                 return false;
1111         }
1113         /**
1114          * Allows you to change which class SimplePie uses for handling feed items.
1115          * Useful when you are overloading or extending SimplePie's default classes.
1116          *
1117          * @access public
1118          * @param string $class Name of custom class.
1119          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1120          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1121          */
1122         function set_item_class($class = 'SimplePie_Item')
1123         {
1124                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1125                 {
1126                         $this->item_class = $class;
1127                         return true;
1128                 }
1129                 return false;
1130         }
1132         /**
1133          * Allows you to change which class SimplePie uses for handling author data.
1134          * Useful when you are overloading or extending SimplePie's default classes.
1135          *
1136          * @access public
1137          * @param string $class Name of custom class.
1138          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1139          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1140          */
1141         function set_author_class($class = 'SimplePie_Author')
1142         {
1143                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1144                 {
1145                         $this->author_class = $class;
1146                         return true;
1147                 }
1148                 return false;
1149         }
1151         /**
1152          * Allows you to change which class SimplePie uses for handling category data.
1153          * Useful when you are overloading or extending SimplePie's default classes.
1154          *
1155          * @access public
1156          * @param string $class Name of custom class.
1157          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1158          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1159          */
1160         function set_category_class($class = 'SimplePie_Category')
1161         {
1162                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1163                 {
1164                         $this->category_class = $class;
1165                         return true;
1166                 }
1167                 return false;
1168         }
1170         /**
1171          * Allows you to change which class SimplePie uses for feed enclosures.
1172          * Useful when you are overloading or extending SimplePie's default classes.
1173          *
1174          * @access public
1175          * @param string $class Name of custom class.
1176          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1177          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1178          */
1179         function set_enclosure_class($class = 'SimplePie_Enclosure')
1180         {
1181                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1182                 {
1183                         $this->enclosure_class = $class;
1184                         return true;
1185                 }
1186                 return false;
1187         }
1189         /**
1190          * Allows you to change which class SimplePie uses for <media:text> captions
1191          * Useful when you are overloading or extending SimplePie's default classes.
1192          *
1193          * @access public
1194          * @param string $class Name of custom class.
1195          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1196          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1197          */
1198         function set_caption_class($class = 'SimplePie_Caption')
1199         {
1200                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1201                 {
1202                         $this->caption_class = $class;
1203                         return true;
1204                 }
1205                 return false;
1206         }
1208         /**
1209          * Allows you to change which class SimplePie uses for <media:copyright>
1210          * Useful when you are overloading or extending SimplePie's default classes.
1211          *
1212          * @access public
1213          * @param string $class Name of custom class.
1214          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1215          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1216          */
1217         function set_copyright_class($class = 'SimplePie_Copyright')
1218         {
1219                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1220                 {
1221                         $this->copyright_class = $class;
1222                         return true;
1223                 }
1224                 return false;
1225         }
1227         /**
1228          * Allows you to change which class SimplePie uses for <media:credit>
1229          * Useful when you are overloading or extending SimplePie's default classes.
1230          *
1231          * @access public
1232          * @param string $class Name of custom class.
1233          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1234          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1235          */
1236         function set_credit_class($class = 'SimplePie_Credit')
1237         {
1238                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1239                 {
1240                         $this->credit_class = $class;
1241                         return true;
1242                 }
1243                 return false;
1244         }
1246         /**
1247          * Allows you to change which class SimplePie uses for <media:rating>
1248          * Useful when you are overloading or extending SimplePie's default classes.
1249          *
1250          * @access public
1251          * @param string $class Name of custom class.
1252          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1253          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1254          */
1255         function set_rating_class($class = 'SimplePie_Rating')
1256         {
1257                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1258                 {
1259                         $this->rating_class = $class;
1260                         return true;
1261                 }
1262                 return false;
1263         }
1265         /**
1266          * Allows you to change which class SimplePie uses for <media:restriction>
1267          * Useful when you are overloading or extending SimplePie's default classes.
1268          *
1269          * @access public
1270          * @param string $class Name of custom class.
1271          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1272          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1273          */
1274         function set_restriction_class($class = 'SimplePie_Restriction')
1275         {
1276                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1277                 {
1278                         $this->restriction_class = $class;
1279                         return true;
1280                 }
1281                 return false;
1282         }
1284         /**
1285          * Allows you to change which class SimplePie uses for content-type sniffing.
1286          * Useful when you are overloading or extending SimplePie's default classes.
1287          *
1288          * @access public
1289          * @param string $class Name of custom class.
1290          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1291          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1292          */
1293         function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1294         {
1295                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1296                 {
1297                         $this->content_type_sniffer_class = $class;
1298                         return true;
1299                 }
1300                 return false;
1301         }
1303         /**
1304          * Allows you to change which class SimplePie uses item sources.
1305          * Useful when you are overloading or extending SimplePie's default classes.
1306          *
1307          * @access public
1308          * @param string $class Name of custom class.
1309          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1310          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1311          */
1312         function set_source_class($class = 'SimplePie_Source')
1313         {
1314                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1315                 {
1316                         $this->source_class = $class;
1317                         return true;
1318                 }
1319                 return false;
1320         }
1322         /**
1323          * Allows you to override the default user agent string.
1324          *
1325          * @access public
1326          * @param string $ua New user agent string.
1327          */
1328         function set_useragent($ua = SIMPLEPIE_USERAGENT)
1329         {
1330                 $this->useragent = (string) $ua;
1331         }
1333         /**
1334          * Set callback function to create cache filename with
1335          *
1336          * @access public
1337          * @param mixed $function Callback function
1338          */
1339         function set_cache_name_function($function = 'md5')
1340         {
1341                 if (is_callable($function))
1342                 {
1343                         $this->cache_name_function = $function;
1344                 }
1345         }
1347         /**
1348          * Set javascript query string parameter
1349          *
1350          * @access public
1351          * @param mixed $get Javascript query string parameter
1352          */
1353         function set_javascript($get = 'js')
1354         {
1355                 if ($get)
1356                 {
1357                         $this->javascript = (string) $get;
1358                 }
1359                 else
1360                 {
1361                         $this->javascript = false;
1362                 }
1363         }
1365         /**
1366          * Set options to make SP as fast as possible.  Forgoes a
1367          * substantial amount of data sanitization in favor of speed.
1368          *
1369          * @access public
1370          * @param bool $set Whether to set them or not
1371          */
1372         function set_stupidly_fast($set = false)
1373         {
1374                 if ($set)
1375                 {
1376                         $this->enable_order_by_date(false);
1377                         $this->remove_div(false);
1378                         $this->strip_comments(false);
1379                         $this->strip_htmltags(false);
1380                         $this->strip_attributes(false);
1381                         $this->set_image_handler(false);
1382                 }
1383         }
1385         /**
1386          * Set maximum number of feeds to check with autodiscovery
1387          *
1388          * @access public
1389          * @param int $max Maximum number of feeds to check
1390          */
1391         function set_max_checked_feeds($max = 10)
1392         {
1393                 $this->max_checked_feeds = (int) $max;
1394         }
1396         function remove_div($enable = true)
1397         {
1398                 $this->sanitize->remove_div($enable);
1399         }
1401         function strip_htmltags($tags = '', $encode = null)
1402         {
1403                 if ($tags === '')
1404                 {
1405                         $tags = $this->strip_htmltags;
1406                 }
1407                 $this->sanitize->strip_htmltags($tags);
1408                 if ($encode !== null)
1409                 {
1410                         $this->sanitize->encode_instead_of_strip($tags);
1411                 }
1412         }
1414         function encode_instead_of_strip($enable = true)
1415         {
1416                 $this->sanitize->encode_instead_of_strip($enable);
1417         }
1419         function strip_attributes($attribs = '')
1420         {
1421                 if ($attribs === '')
1422                 {
1423                         $attribs = $this->strip_attributes;
1424                 }
1425                 $this->sanitize->strip_attributes($attribs);
1426         }
1428         function set_output_encoding($encoding = 'UTF-8')
1429         {
1430                 $this->sanitize->set_output_encoding($encoding);
1431         }
1433         function strip_comments($strip = false)
1434         {
1435                 $this->sanitize->strip_comments($strip);
1436         }
1438         /**
1439          * Set element/attribute key/value pairs of HTML attributes
1440          * containing URLs that need to be resolved relative to the feed
1441          *
1442          * @access public
1443          * @since 1.0
1444          * @param array $element_attribute Element/attribute key/value pairs
1445          */
1446         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'))
1447         {
1448                 $this->sanitize->set_url_replacements($element_attribute);
1449         }
1451         /**
1452          * Set the handler to enable the display of cached favicons.
1453          *
1454          * @access public
1455          * @param str $page Web-accessible path to the handler_favicon.php file.
1456          * @param str $qs The query string that the value should be passed to.
1457          */
1458         function set_favicon_handler($page = false, $qs = 'i')
1459         {
1460                 if ($page !== false)
1461                 {
1462                         $this->favicon_handler = $page . '?' . $qs . '=';
1463                 }
1464                 else
1465                 {
1466                         $this->favicon_handler = '';
1467                 }
1468         }
1470         /**
1471          * Set the handler to enable the display of cached images.
1472          *
1473          * @access public
1474          * @param str $page Web-accessible path to the handler_image.php file.
1475          * @param str $qs The query string that the value should be passed to.
1476          */
1477         function set_image_handler($page = false, $qs = 'i')
1478         {
1479                 if ($page !== false)
1480                 {
1481                         $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1482                 }
1483                 else
1484                 {
1485                         $this->image_handler = '';
1486                 }
1487         }
1489         /**
1490          * Set the limit for items returned per-feed with multifeeds.
1491          *
1492          * @access public
1493          * @param integer $limit The maximum number of items to return.
1494          */
1495         function set_item_limit($limit = 0)
1496         {
1497                 $this->item_limit = (int) $limit;
1498         }
1500         function init()
1501         {
1502                 // Check absolute bare minimum requirements.
1503                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1504                 {
1505                         return false;
1506                 }
1507                 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1508                 elseif (!extension_loaded('xmlreader'))
1509                 {
1510                         static $xml_is_sane = null;
1511                         if ($xml_is_sane === null)
1512                         {
1513                                 $parser_check = xml_parser_create();
1514                                 xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1515                                 xml_parser_free($parser_check);
1516                                 $xml_is_sane = isset($values[0]['value']);
1517                         }
1518                         if (!$xml_is_sane)
1519                         {
1520                                 return false;
1521                         }
1522                 }
1524                 if (isset($_GET[$this->javascript]))
1525                 {
1526                         SimplePie_Misc::output_javascript();
1527                         exit;
1528                 }
1530                 // Pass whatever was set with config options over to the sanitizer.
1531                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1532                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1534                 if ($this->feed_url !== null || $this->raw_data !== null)
1535                 {
1536                         $this->data = array();
1537                         $this->multifeed_objects = array();
1538                         $cache = false;
1540                         if ($this->feed_url !== null)
1541                         {
1542                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1543                                 // Decide whether to enable caching
1544                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1545                                 {
1546                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1547                                 }
1548                                 // If it's enabled and we don't want an XML dump, use the cache
1549                                 if ($cache && !$this->xml_dump)
1550                                 {
1551                                         // Load the Cache
1552                                         $this->data = $cache->load();
1553                                         if (!empty($this->data))
1554                                         {
1555                                                 // If the cache is for an outdated build of SimplePie
1556                                                 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1557                                                 {
1558                                                         $cache->unlink();
1559                                                         $this->data = array();
1560                                                 }
1561                                                 // If we've hit a collision just rerun it with caching disabled
1562                                                 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1563                                                 {
1564                                                         $cache = false;
1565                                                         $this->data = array();
1566                                                 }
1567                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1568                                                 elseif (isset($this->data['feed_url']))
1569                                                 {
1570                                                         // If the autodiscovery cache is still valid use it.
1571                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1572                                                         {
1573                                                                 // Do not need to do feed autodiscovery yet.
1574                                                                 if ($this->data['feed_url'] === $this->data['url'])
1575                                                                 {
1576                                                                         $cache->unlink();
1577                                                                         $this->data = array();
1578                                                                 }
1579                                                                 else
1580                                                                 {
1581                                                                         $this->set_feed_url($this->data['feed_url']);
1582                                                                         return $this->init();
1583                                                                 }
1584                                                         }
1585                                                 }
1586                                                 // Check if the cache has been updated
1587                                                 elseif ($cache->mtime() + $this->cache_duration < time())
1588                                                 {
1589                                                         // If we have last-modified and/or etag set
1590                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1591                                                         {
1592                                                                 $headers = array();
1593                                                                 if (isset($this->data['headers']['last-modified']))
1594                                                                 {
1595                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1596                                                                 }
1597                                                                 if (isset($this->data['headers']['etag']))
1598                                                                 {
1599                                                                         $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1600                                                                 }
1601                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1602                                                                 if ($file->success)
1603                                                                 {
1604                                                                         if ($file->status_code === 304)
1605                                                                         {
1606                                                                                 $cache->touch();
1607                                                                                 return true;
1608                                                                         }
1609                                                                         else
1610                                                                         {
1611                                                                                 $headers = $file->headers;
1612                                                                         }
1613                                                                 }
1614                                                                 else
1615                                                                 {
1616                                                                         unset($file);
1617                                                                 }
1618                                                         }
1619                                                 }
1620                                                 // If the cache is still valid, just return true
1621                                                 else
1622                                                 {
1623                                                         return true;
1624                                                 }
1625                                         }
1626                                         // If the cache is empty, delete it
1627                                         else
1628                                         {
1629                                                 $cache->unlink();
1630                                                 $this->data = array();
1631                                         }
1632                                 }
1633                                 // 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.
1634                                 if (!isset($file))
1635                                 {
1636                                         if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1637                                         {
1638                                                 $file =& $this->file;
1639                                         }
1640                                         else
1641                                         {
1642                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1643                                         }
1644                                 }
1645                                 // If the file connection has an error, set SimplePie::error to that and quit
1646                                 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1647                                 {
1648                                         $this->error = $file->error;
1649                                         if (!empty($this->data))
1650                                         {
1651                                                 return true;
1652                                         }
1653                                         else
1654                                         {
1655                                                 return false;
1656                                         }
1657                                 }
1659                                 if (!$this->force_feed)
1660                                 {
1661                                         // Check if the supplied URL is a feed, if it isn't, look for it.
1662                                         $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1663                                         if (!$locate->is_feed($file))
1664                                         {
1665                                                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1666                                                 unset($file);
1667                                                 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1668                                                 {
1669                                                         if ($cache)
1670                                                         {
1671                                                                 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1672                                                                 if (!$cache->save($this))
1673                                                                 {
1674                                                                         trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
1675                                                                 }
1676                                                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1677                                                         }
1678                                                         $this->feed_url = $file->url;
1679                                                 }
1680                                                 else
1681                                                 {
1682                                                         $this->error = "A feed could not be found at $this->feed_url";
1683                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1684                                                         return false;
1685                                                 }
1686                                         }
1687                                         $locate = null;
1688                                 }
1690                                 $headers = $file->headers;
1691                                 $data = $file->body;
1692                                 $sniffer =& new $this->content_type_sniffer_class($file);
1693                                 $sniffed = $sniffer->get_type();
1694                         }
1695                         else
1696                         {
1697                                 $data = $this->raw_data;
1698                         }
1700                         // Set up array of possible encodings
1701                         $encodings = array();
1703                         // First check to see if input has been overridden.
1704                         if ($this->input_encoding !== false)
1705                         {
1706                                 $encodings[] = $this->input_encoding;
1707                         }
1709                         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1710                         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1712                         // RFC 3023 (only applies to sniffed content)
1713                         if (isset($sniffed))
1714                         {
1715                                 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1716                                 {
1717                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1718                                         {
1719                                                 $encodings[] = strtoupper($charset[1]);
1720                                         }
1721                                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1722                                         $encodings[] = 'UTF-8';
1723                                 }
1724                                 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1725                                 {
1726                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1727                                         {
1728                                                 $encodings[] = $charset[1];
1729                                         }
1730                                         $encodings[] = 'US-ASCII';
1731                                 }
1732                                 // Text MIME-type default
1733                                 elseif (substr($sniffed, 0, 5) === 'text/')
1734                                 {
1735                                         $encodings[] = 'US-ASCII';
1736                                 }
1737                         }
1739                         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1740                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1741                         $encodings[] = 'UTF-8';
1742                         $encodings[] = 'ISO-8859-1';
1744                         // There's no point in trying an encoding twice
1745                         $encodings = array_unique($encodings);
1747                         // If we want the XML, just output that with the most likely encoding and quit
1748                         if ($this->xml_dump)
1749                         {
1750                                 header('Content-type: text/xml; charset=' . $encodings[0]);
1751                                 echo $data;
1752                                 exit;
1753                         }
1755                         // Loop through each possible encoding, till we return something, or run out of possibilities
1756                         foreach ($encodings as $encoding)
1757                         {
1758                                 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1759                                 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1760                                 {
1761                                         // Create new parser
1762                                         $parser =& new $this->parser_class();
1764                                         // If it's parsed fine
1765                                         if ($parser->parse($utf8_data, 'UTF-8'))
1766                                         {
1767                                                 $this->data = $parser->get_data();
1768                                                 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1769                                                 {
1770                                                         if (isset($headers))
1771                                                         {
1772                                                                 $this->data['headers'] = $headers;
1773                                                         }
1774                                                         $this->data['build'] = SIMPLEPIE_BUILD;
1776                                                         // Cache the file if caching is enabled
1777                                                         if ($cache && !$cache->save($this))
1778                                                         {
1779                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1780                                                         }
1781                                                         return true;
1782                                                 }
1783                                                 else
1784                                                 {
1785                                                         $this->error = "A feed could not be found at $this->feed_url";
1786                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1787                                                         return false;
1788                                                 }
1789                                         }
1790                                 }
1791                         }
1792                         if(isset($parser))
1793                         {
1794                                 // We have an error, just set SimplePie_Misc::error to it and quit
1795                                 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1796                         }
1797                         else
1798                         {
1799                                 $this->error = 'The data could not be converted to UTF-8';
1800                         }
1801                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1802                         return false;
1803                 }
1804                 elseif (!empty($this->multifeed_url))
1805                 {
1806                         $i = 0;
1807                         $success = 0;
1808                         $this->multifeed_objects = array();
1809                         foreach ($this->multifeed_url as $url)
1810                         {
1811                                 if (SIMPLEPIE_PHP5)
1812                                 {
1813                                         // This keyword needs to defy coding standards for PHP4 compatibility
1814                                         $this->multifeed_objects[$i] = clone($this);
1815                                 }
1816                                 else
1817                                 {
1818                                         $this->multifeed_objects[$i] = $this;
1819                                 }
1820                                 $this->multifeed_objects[$i]->set_feed_url($url);
1821                                 $success |= $this->multifeed_objects[$i]->init();
1822                                 $i++;
1823                         }
1824                         return (bool) $success;
1825                 }
1826                 else
1827                 {
1828                         return false;
1829                 }
1830         }
1832         /**
1833          * Return the error message for the occured error
1834          *
1835          * @access public
1836          * @return string Error message
1837          */
1838         function error()
1839         {
1840                 return $this->error;
1841         }
1843         function get_encoding()
1844         {
1845                 return $this->sanitize->output_encoding;
1846         }
1848         function handle_content_type($mime = 'text/html')
1849         {
1850                 if (!headers_sent())
1851                 {
1852                         $header = "Content-type: $mime;";
1853                         if ($this->get_encoding())
1854                         {
1855                                 $header .= ' charset=' . $this->get_encoding();
1856                         }
1857                         else
1858                         {
1859                                 $header .= ' charset=UTF-8';
1860                         }
1861                         header($header);
1862                 }
1863         }
1865         function get_type()
1866         {
1867                 if (!isset($this->data['type']))
1868                 {
1869                         $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1870                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1871                         {
1872                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1873                         }
1874                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1875                         {
1876                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1877                         }
1878                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1879                         {
1880                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1881                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1882                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1883                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1884                                 {
1885                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1886                                 }
1887                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1888                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1889                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1890                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1891                                 {
1892                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1893                                 }
1894                         }
1895                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1896                         {
1897                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1898                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1899                                 {
1900                                         switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1901                                         {
1902                                                 case '0.91':
1903                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1904                                                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1905                                                         {
1906                                                                 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1907                                                                 {
1908                                                                         case '0':
1909                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1910                                                                                 break;
1912                                                                         case '24':
1913                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1914                                                                                 break;
1915                                                                 }
1916                                                         }
1917                                                         break;
1919                                                 case '0.92':
1920                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1921                                                         break;
1923                                                 case '0.93':
1924                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1925                                                         break;
1927                                                 case '0.94':
1928                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1929                                                         break;
1931                                                 case '2.0':
1932                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1933                                                         break;
1934                                         }
1935                                 }
1936                         }
1937                         else
1938                         {
1939                                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1940                         }
1941                 }
1942                 return $this->data['type'];
1943         }
1945         /**
1946          * Returns the URL for the favicon of the feed's website.
1947          *
1948          * @todo Cache atom:icon
1949          * @access public
1950          * @since 1.0
1951          */
1952         function get_favicon()
1953         {
1954                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1955                 {
1956                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1957                 }
1958                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1959                 {
1960                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1962                         if ($this->cache && $this->favicon_handler)
1963                         {
1964                                 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1965                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1967                                 if ($cache->load())
1968                                 {
1969                                         return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1970                                 }
1971                                 else
1972                                 {
1973                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1975                                         if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1976                                         {
1977                                                 $sniffer =& new $this->content_type_sniffer_class($file);
1978                                                 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1979                                                 {
1980                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1981                                                         {
1982                                                                 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1983                                                         }
1984                                                         else
1985                                                         {
1986                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1987                                                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1988                                                         }
1989                                                 }
1990                                                 // not an image
1991                                                 else
1992                                                 {
1993                                                         return false;
1994                                                 }
1995                                         }
1996                                 }
1997                         }
1998                         else
1999                         {
2000                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2001                         }
2002                 }
2003                 return false;
2004         }
2006         /**
2007          * @todo If we have a perm redirect we should return the new URL
2008          * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2009          * @todo Also, |atom:link|@rel=self
2010          */
2011         function subscribe_url()
2012         {
2013                 if ($this->feed_url !== null)
2014                 {
2015                         return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2016                 }
2017                 else
2018                 {
2019                         return null;
2020                 }
2021         }
2023         function subscribe_feed()
2024         {
2025                 if ($this->feed_url !== null)
2026                 {
2027                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2028                 }
2029                 else
2030                 {
2031                         return null;
2032                 }
2033         }
2035         function subscribe_outlook()
2036         {
2037                 if ($this->feed_url !== null)
2038                 {
2039                         return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2040                 }
2041                 else
2042                 {
2043                         return null;
2044                 }
2045         }
2047         function subscribe_podcast()
2048         {
2049                 if ($this->feed_url !== null)
2050                 {
2051                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2052                 }
2053                 else
2054                 {
2055                         return null;
2056                 }
2057         }
2059         function subscribe_itunes()
2060         {
2061                 if ($this->feed_url !== null)
2062                 {
2063                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2064                 }
2065                 else
2066                 {
2067                         return null;
2068                 }
2069         }
2071         /**
2072          * Creates the subscribe_* methods' return data
2073          *
2074          * @access private
2075          * @param string $feed_url String to prefix to the feed URL
2076          * @param string $site_url String to prefix to the site URL (and
2077          * suffix to the feed URL)
2078          * @return mixed URL if feed exists, false otherwise
2079          */
2080         function subscribe_service($feed_url, $site_url = null)
2081         {
2082                 if ($this->subscribe_url())
2083                 {
2084                         $return = $feed_url . rawurlencode($this->feed_url);
2085                         if ($site_url !== null && $this->get_link() !== null)
2086                         {
2087                                 $return .= $site_url . rawurlencode($this->get_link());
2088                         }
2089                         return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2090                 }
2091                 else
2092                 {
2093                         return null;
2094                 }
2095         }
2097         function subscribe_aol()
2098         {
2099                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2100         }
2102         function subscribe_bloglines()
2103         {
2104                 return $this->subscribe_service('http://www.bloglines.com/sub/');
2105         }
2107         function subscribe_eskobo()
2108         {
2109                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2110         }
2112         function subscribe_feedfeeds()
2113         {
2114                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2115         }
2117         function subscribe_feedster()
2118         {
2119                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2120         }
2122         function subscribe_google()
2123         {
2124                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2125         }
2127         function subscribe_gritwire()
2128         {
2129                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2130         }
2132         function subscribe_msn()
2133         {
2134                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2135         }
2137         function subscribe_netvibes()
2138         {
2139                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2140         }
2142         function subscribe_newsburst()
2143         {
2144                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2145         }
2147         function subscribe_newsgator()
2148         {
2149                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2150         }
2152         function subscribe_odeo()
2153         {
2154                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2155         }
2157         function subscribe_podnova()
2158         {
2159                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2160         }
2162         function subscribe_rojo()
2163         {
2164                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2165         }
2167         function subscribe_yahoo()
2168         {
2169                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2170         }
2172         function get_feed_tags($namespace, $tag)
2173         {
2174                 $type = $this->get_type();
2175                 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2176                 {
2177                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2178                         {
2179                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2180                         }
2181                 }
2182                 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2183                 {
2184                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2185                         {
2186                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2187                         }
2188                 }
2189                 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2190                 {
2191                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2192                         {
2193                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2194                         }
2195                 }
2196                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2197                 {
2198                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2199                         {
2200                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2201                         }
2202                 }
2203                 return null;
2204         }
2206         function get_channel_tags($namespace, $tag)
2207         {
2208                 $type = $this->get_type();
2209                 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2210                 {
2211                         if ($return = $this->get_feed_tags($namespace, $tag))
2212                         {
2213                                 return $return;
2214                         }
2215                 }
2216                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2217                 {
2218                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2219                         {
2220                                 if (isset($channel[0]['child'][$namespace][$tag]))
2221                                 {
2222                                         return $channel[0]['child'][$namespace][$tag];
2223                                 }
2224                         }
2225                 }
2226                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2227                 {
2228                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2229                         {
2230                                 if (isset($channel[0]['child'][$namespace][$tag]))
2231                                 {
2232                                         return $channel[0]['child'][$namespace][$tag];
2233                                 }
2234                         }
2235                 }
2236                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2237                 {
2238                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2239                         {
2240                                 if (isset($channel[0]['child'][$namespace][$tag]))
2241                                 {
2242                                         return $channel[0]['child'][$namespace][$tag];
2243                                 }
2244                         }
2245                 }
2246                 return null;
2247         }
2249         function get_image_tags($namespace, $tag)
2250         {
2251                 $type = $this->get_type();
2252                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2253                 {
2254                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2255                         {
2256                                 if (isset($image[0]['child'][$namespace][$tag]))
2257                                 {
2258                                         return $image[0]['child'][$namespace][$tag];
2259                                 }
2260                         }
2261                 }
2262                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2263                 {
2264                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2265                         {
2266                                 if (isset($image[0]['child'][$namespace][$tag]))
2267                                 {
2268                                         return $image[0]['child'][$namespace][$tag];
2269                                 }
2270                         }
2271                 }
2272                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2273                 {
2274                         if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2275                         {
2276                                 if (isset($image[0]['child'][$namespace][$tag]))
2277                                 {
2278                                         return $image[0]['child'][$namespace][$tag];
2279                                 }
2280                         }
2281                 }
2282                 return null;
2283         }
2285         function get_base($element = array())
2286         {
2287                 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2288                 {
2289                         return $element['xml_base'];
2290                 }
2291                 elseif ($this->get_link() !== null)
2292                 {
2293                         return $this->get_link();
2294                 }
2295                 else
2296                 {
2297                         return $this->subscribe_url();
2298                 }
2299         }
2301         function sanitize($data, $type, $base = '')
2302         {
2303                 return $this->sanitize->sanitize($data, $type, $base);
2304         }
2306         function get_title()
2307         {
2308                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2309                 {
2310                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2311                 }
2312                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2313                 {
2314                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2315                 }
2316                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2317                 {
2318                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2319                 }
2320                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2321                 {
2322                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2323                 }
2324                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2325                 {
2326                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2327                 }
2328                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2329                 {
2330                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2331                 }
2332                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2333                 {
2334                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2335                 }
2336                 else
2337                 {
2338                         return null;
2339                 }
2340         }
2342         function get_category($key = 0)
2343         {
2344                 $categories = $this->get_categories();
2345                 if (isset($categories[$key]))
2346                 {
2347                         return $categories[$key];
2348                 }
2349                 else
2350                 {
2351                         return null;
2352                 }
2353         }
2355         function get_categories()
2356         {
2357                 $categories = array();
2359                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2360                 {
2361                         $term = null;
2362                         $scheme = null;
2363                         $label = null;
2364                         if (isset($category['attribs']['']['term']))
2365                         {
2366                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2367                         }
2368                         if (isset($category['attribs']['']['scheme']))
2369                         {
2370                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2371                         }
2372                         if (isset($category['attribs']['']['label']))
2373                         {
2374                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2375                         }
2376                         $categories[] =& new $this->category_class($term, $scheme, $label);
2377                 }
2378                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2379                 {
2380                         // This is really the label, but keep this as the term also for BC.
2381                         // Label will also work on retrieving because that falls back to term.
2382                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2383                         if (isset($category['attribs']['']['domain']))
2384                         {
2385                                 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2386                         }
2387                         else
2388                         {
2389                                 $scheme = null;
2390                         }
2391                         $categories[] =& new $this->category_class($term, $scheme, null);
2392                 }
2393                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2394                 {
2395                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2396                 }
2397                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2398                 {
2399                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2400                 }
2402                 if (!empty($categories))
2403                 {
2404                         return SimplePie_Misc::array_unique($categories);
2405                 }
2406                 else
2407                 {
2408                         return null;
2409                 }
2410         }
2412         function get_author($key = 0)
2413         {
2414                 $authors = $this->get_authors();
2415                 if (isset($authors[$key]))
2416                 {
2417                         return $authors[$key];
2418                 }
2419                 else
2420                 {
2421                         return null;
2422                 }
2423         }
2425         function get_authors()
2426         {
2427                 $authors = array();
2428                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2429                 {
2430                         $name = null;
2431                         $uri = null;
2432                         $email = null;
2433                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2434                         {
2435                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2436                         }
2437                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2438                         {
2439                                 $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]));
2440                         }
2441                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2442                         {
2443                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2444                         }
2445                         if ($name !== null || $email !== null || $uri !== null)
2446                         {
2447                                 $authors[] =& new $this->author_class($name, $uri, $email);
2448                         }
2449                 }
2450                 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2451                 {
2452                         $name = null;
2453                         $url = null;
2454                         $email = null;
2455                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2456                         {
2457                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2458                         }
2459                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2460                         {
2461                                 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2462                         }
2463                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2464                         {
2465                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2466                         }
2467                         if ($name !== null || $email !== null || $url !== null)
2468                         {
2469                                 $authors[] =& new $this->author_class($name, $url, $email);
2470                         }
2471                 }
2472                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2473                 {
2474                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2475                 }
2476                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2477                 {
2478                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2479                 }
2480                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2481                 {
2482                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2483                 }
2485                 if (!empty($authors))
2486                 {
2487                         return SimplePie_Misc::array_unique($authors);
2488                 }
2489                 else
2490                 {
2491                         return null;
2492                 }
2493         }
2495         function get_contributor($key = 0)
2496         {
2497                 $contributors = $this->get_contributors();
2498                 if (isset($contributors[$key]))
2499                 {
2500                         return $contributors[$key];
2501                 }
2502                 else
2503                 {
2504                         return null;
2505                 }
2506         }
2508         function get_contributors()
2509         {
2510                 $contributors = array();
2511                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2512                 {
2513                         $name = null;
2514                         $uri = null;
2515                         $email = null;
2516                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2517                         {
2518                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2519                         }
2520                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2521                         {
2522                                 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2523                         }
2524                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2525                         {
2526                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2527                         }
2528                         if ($name !== null || $email !== null || $uri !== null)
2529                         {
2530                                 $contributors[] =& new $this->author_class($name, $uri, $email);
2531                         }
2532                 }
2533                 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2534                 {
2535                         $name = null;
2536                         $url = null;
2537                         $email = null;
2538                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2539                         {
2540                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2541                         }
2542                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2543                         {
2544                                 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2545                         }
2546                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2547                         {
2548                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2549                         }
2550                         if ($name !== null || $email !== null || $url !== null)
2551                         {
2552                                 $contributors[] =& new $this->author_class($name, $url, $email);
2553                         }
2554                 }
2556                 if (!empty($contributors))
2557                 {
2558                         return SimplePie_Misc::array_unique($contributors);
2559                 }
2560                 else
2561                 {
2562                         return null;
2563                 }
2564         }
2566         function get_link($key = 0, $rel = 'alternate')
2567         {
2568                 $links = $this->get_links($rel);
2569                 if (isset($links[$key]))
2570                 {
2571                         return $links[$key];
2572                 }
2573                 else
2574                 {
2575                         return null;
2576                 }
2577         }
2579         /**
2580          * Added for parity between the parent-level and the item/entry-level.
2581          */
2582         function get_permalink()
2583         {
2584                 return $this->get_link(0);
2585         }
2587         function get_links($rel = 'alternate')
2588         {
2589                 if (!isset($this->data['links']))
2590                 {
2591                         $this->data['links'] = array();
2592                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2593                         {
2594                                 foreach ($links as $link)
2595                                 {
2596                                         if (isset($link['attribs']['']['href']))
2597                                         {
2598                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2599                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2600                                         }
2601                                 }
2602                         }
2603                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2604                         {
2605                                 foreach ($links as $link)
2606                                 {
2607                                         if (isset($link['attribs']['']['href']))
2608                                         {
2609                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2610                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2612                                         }
2613                                 }
2614                         }
2615                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2616                         {
2617                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2618                         }
2619                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2620                         {
2621                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2622                         }
2623                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2624                         {
2625                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2626                         }
2628                         $keys = array_keys($this->data['links']);
2629                         foreach ($keys as $key)
2630                         {
2631                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
2632                                 {
2633                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2634                                         {
2635                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2636                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2637                                         }
2638                                         else
2639                                         {
2640                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2641                                         }
2642                                 }
2643                                 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2644                                 {
2645                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2646                                 }
2647                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2648                         }
2649                 }
2651                 if (isset($this->data['links'][$rel]))
2652                 {
2653                         return $this->data['links'][$rel];
2654                 }
2655                 else
2656                 {
2657                         return null;
2658                 }
2659         }
2661         function get_all_discovered_feeds()
2662         {
2663                 return $this->all_discovered_feeds;
2664         }
2666         function get_description()
2667         {
2668                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2669                 {
2670                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2671                 }
2672                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2673                 {
2674                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2675                 }
2676                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2677                 {
2678                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2679                 }
2680                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2681                 {
2682                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2683                 }
2684                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2685                 {
2686                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2687                 }
2688                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2689                 {
2690                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2691                 }
2692                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2693                 {
2694                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2695                 }
2696                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2697                 {
2698                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2699                 }
2700                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2701                 {
2702                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2703                 }
2704                 else
2705                 {
2706                         return null;
2707                 }
2708         }
2710         function get_copyright()
2711         {
2712                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2713                 {
2714                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2715                 }
2716                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2717                 {
2718                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2719                 }
2720                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2721                 {
2722                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2723                 }
2724                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2725                 {
2726                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2727                 }
2728                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2729                 {
2730                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2731                 }
2732                 else
2733                 {
2734                         return null;
2735                 }
2736         }
2738         function get_language()
2739         {
2740                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2741                 {
2742                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2743                 }
2744                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2745                 {
2746                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2747                 }
2748                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2749                 {
2750                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2751                 }
2752                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2753                 {
2754                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2755                 }
2756                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2757                 {
2758                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2759                 }
2760                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2761                 {
2762                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2763                 }
2764                 elseif (isset($this->data['headers']['content-language']))
2765                 {
2766                         return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2767                 }
2768                 else
2769                 {
2770                         return null;
2771                 }
2772         }
2774         function get_latitude()
2775         {
2776                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2777                 {
2778                         return (float) $return[0]['data'];
2779                 }
2780                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2781                 {
2782                         return (float) $match[1];
2783                 }
2784                 else
2785                 {
2786                         return null;
2787                 }
2788         }
2790         function get_longitude()
2791         {
2792                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2793                 {
2794                         return (float) $return[0]['data'];
2795                 }
2796                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2797                 {
2798                         return (float) $return[0]['data'];
2799                 }
2800                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2801                 {
2802                         return (float) $match[2];
2803                 }
2804                 else
2805                 {
2806                         return null;
2807                 }
2808         }
2810         function get_image_title()
2811         {
2812                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2813                 {
2814                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2815                 }
2816                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2817                 {
2818                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2819                 }
2820                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2821                 {
2822                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2823                 }
2824                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2825                 {
2826                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2827                 }
2828                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2829                 {
2830                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2831                 }
2832                 else
2833                 {
2834                         return null;
2835                 }
2836         }
2838         function get_image_url()
2839         {
2840                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2841                 {
2842                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2843                 }
2844                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2845                 {
2846                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2847                 }
2848                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2849                 {
2850                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2851                 }
2852                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2853                 {
2854                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2855                 }
2856                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2857                 {
2858                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859                 }
2860                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2861                 {
2862                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2863                 }
2864                 else
2865                 {
2866                         return null;
2867                 }
2868         }
2870         function get_image_link()
2871         {
2872                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2873                 {
2874                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2875                 }
2876                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2877                 {
2878                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2879                 }
2880                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2881                 {
2882                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2883                 }
2884                 else
2885                 {
2886                         return null;
2887                 }
2888         }
2890         function get_image_width()
2891         {
2892                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2893                 {
2894                         return round($return[0]['data']);
2895                 }
2896                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2897                 {
2898                         return 88.0;
2899                 }
2900                 else
2901                 {
2902                         return null;
2903                 }
2904         }
2906         function get_image_height()
2907         {
2908                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2909                 {
2910                         return round($return[0]['data']);
2911                 }
2912                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2913                 {
2914                         return 31.0;
2915                 }
2916                 else
2917                 {
2918                         return null;
2919                 }
2920         }
2922         function get_item_quantity($max = 0)
2923         {
2924                 $max = (int) $max;
2925                 $qty = count($this->get_items());
2926                 if ($max === 0)
2927                 {
2928                         return $qty;
2929                 }
2930                 else
2931                 {
2932                         return ($qty > $max) ? $max : $qty;
2933                 }
2934         }
2936         function get_item($key = 0)
2937         {
2938                 $items = $this->get_items();
2939                 if (isset($items[$key]))
2940                 {
2941                         return $items[$key];
2942                 }
2943                 else
2944                 {
2945                         return null;
2946                 }
2947         }
2949         function get_items($start = 0, $end = 0)
2950         {
2951                 if (!isset($this->data['items']))
2952                 {
2953                         if (!empty($this->multifeed_objects))
2954                         {
2955                                 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2956                         }
2957                         else
2958                         {
2959                                 $this->data['items'] = array();
2960                                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2961                                 {
2962                                         $keys = array_keys($items);
2963                                         foreach ($keys as $key)
2964                                         {
2965                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2966                                         }
2967                                 }
2968                                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2969                                 {
2970                                         $keys = array_keys($items);
2971                                         foreach ($keys as $key)
2972                                         {
2973                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2974                                         }
2975                                 }
2976                                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2977                                 {
2978                                         $keys = array_keys($items);
2979                                         foreach ($keys as $key)
2980                                         {
2981                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2982                                         }
2983                                 }
2984                                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2985                                 {
2986                                         $keys = array_keys($items);
2987                                         foreach ($keys as $key)
2988                                         {
2989                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2990                                         }
2991                                 }
2992                                 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2993                                 {
2994                                         $keys = array_keys($items);
2995                                         foreach ($keys as $key)
2996                                         {
2997                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2998                                         }
2999                                 }
3000                         }
3001                 }