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